diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index a566ba28b8de..798ced9a6286 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -622,9 +622,8 @@ impl Parser { self.input.prev_span(), SyntaxError::TS1029("abstract".into(), "override".into()), ); - } else { - is_abstract = true; } + is_abstract = true; } "override" => { if is_override { @@ -644,9 +643,8 @@ impl Parser { ); } else if !self.ctx().has_super_class { self.emit_err(self.input.prev_span(), SyntaxError::TS4112); - } else { - is_override = true; } + is_override = true; } "readonly" => { let readonly_span = self.input.prev_span(); diff --git a/crates/swc_ecma_parser/tests/tsc/override1.json b/crates/swc_ecma_parser/tests/tsc/override1.json index 06df7166ea3a..c0117987621b 100644 --- a/crates/swc_ecma_parser/tests/tsc/override1.json +++ b/crates/swc_ecma_parser/tests/tsc/override1.json @@ -585,7 +585,7 @@ "accessibility": null, "isAbstract": false, "isOptional": false, - "isOverride": false + "isOverride": true } ], "superClass": null, @@ -1328,7 +1328,7 @@ "accessibility": null, "isAbstract": false, "isOptional": false, - "isOverride": false + "isOverride": true } ], "superClass": null, diff --git a/crates/swc_ecma_parser/tests/tsc/overrideWithoutNoImplicitOverride1.json b/crates/swc_ecma_parser/tests/tsc/overrideWithoutNoImplicitOverride1.json index e43f2e1d97bc..e0afca4bec2e 100644 --- a/crates/swc_ecma_parser/tests/tsc/overrideWithoutNoImplicitOverride1.json +++ b/crates/swc_ecma_parser/tests/tsc/overrideWithoutNoImplicitOverride1.json @@ -85,7 +85,7 @@ "accessibility": null, "isAbstract": false, "isOptional": false, - "isOverride": false + "isOverride": true } ], "superClass": null, @@ -182,7 +182,7 @@ "accessibility": null, "isAbstract": false, "isOptional": false, - "isOverride": false + "isOverride": true } ], "superClass": null, diff --git a/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts b/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts index c0a5ad4b67a7..d7a5f7147bfc 100644 --- a/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts +++ b/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts @@ -5,3 +5,15 @@ export abstract class C {} export default abstract class { } export default abstract class C { } // `abstract class` is not valid as an expression. + +export abstract class C { + abstract prop: number; + abstract method(): void; +} +export class C { + // should still have as abstract even though parent is not + abstract prop: number; + abstract method(): void; + // should be abstract in spite of override in wrong place + override abstract method(): string; +} diff --git a/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts.json b/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts.json index 42512e80a0f4..aea2dc59c043 100644 --- a/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts.json +++ b/crates/swc_ecma_parser/tests/typescript/class/abstract/input.ts.json @@ -2,7 +2,7 @@ "type": "Module", "span": { "start": 1, - "end": 200, + "end": 562, "ctxt": 0 }, "body": [ @@ -148,6 +148,328 @@ "superTypeParams": null, "implements": [] } + }, + { + "type": "ExportDeclaration", + "span": { + "start": 253, + "end": 332, + "ctxt": 0 + }, + "declaration": { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 275, + "end": 276, + "ctxt": 0 + }, + "value": "C", + "optional": false + }, + "declare": false, + "span": { + "start": 260, + "end": 332, + "ctxt": 0 + }, + "decorators": [], + "body": [ + { + "type": "ClassProperty", + "span": { + "start": 281, + "end": 303, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 290, + "end": 294, + "ctxt": 0 + }, + "value": "prop", + "optional": false + }, + "value": null, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 294, + "end": 302, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 296, + "end": 302, + "ctxt": 0 + }, + "kind": "number" + } + }, + "isStatic": false, + "decorators": [], + "accessibility": null, + "isAbstract": true, + "isOptional": false, + "isOverride": false, + "readonly": false, + "declare": false, + "definite": false + }, + { + "type": "ClassMethod", + "span": { + "start": 306, + "end": 330, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 315, + "end": 321, + "ctxt": 0 + }, + "value": "method", + "optional": false + }, + "function": { + "params": [], + "decorators": [], + "span": { + "start": 306, + "end": 330, + "ctxt": 0 + }, + "body": null, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 323, + "end": 329, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 325, + "end": 329, + "ctxt": 0 + }, + "kind": "void" + } + } + }, + "kind": "method", + "isStatic": false, + "accessibility": null, + "isAbstract": true, + "isOptional": false, + "isOverride": false + } + ], + "superClass": null, + "isAbstract": true, + "typeParams": null, + "superTypeParams": null, + "implements": [] + } + }, + { + "type": "ExportDeclaration", + "span": { + "start": 333, + "end": 562, + "ctxt": 0 + }, + "declaration": { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 346, + "end": 347, + "ctxt": 0 + }, + "value": "C", + "optional": false + }, + "declare": false, + "span": { + "start": 340, + "end": 562, + "ctxt": 0 + }, + "decorators": [], + "body": [ + { + "type": "ClassProperty", + "span": { + "start": 413, + "end": 435, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 422, + "end": 426, + "ctxt": 0 + }, + "value": "prop", + "optional": false + }, + "value": null, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 426, + "end": 434, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 428, + "end": 434, + "ctxt": 0 + }, + "kind": "number" + } + }, + "isStatic": false, + "decorators": [], + "accessibility": null, + "isAbstract": true, + "isOptional": false, + "isOverride": false, + "readonly": false, + "declare": false, + "definite": false + }, + { + "type": "ClassMethod", + "span": { + "start": 438, + "end": 462, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 447, + "end": 453, + "ctxt": 0 + }, + "value": "method", + "optional": false + }, + "function": { + "params": [], + "decorators": [], + "span": { + "start": 438, + "end": 462, + "ctxt": 0 + }, + "body": null, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 455, + "end": 461, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 457, + "end": 461, + "ctxt": 0 + }, + "kind": "void" + } + } + }, + "kind": "method", + "isStatic": false, + "accessibility": null, + "isAbstract": true, + "isOptional": false, + "isOverride": false + }, + { + "type": "ClassMethod", + "span": { + "start": 525, + "end": 560, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 543, + "end": 549, + "ctxt": 0 + }, + "value": "method", + "optional": false + }, + "function": { + "params": [], + "decorators": [], + "span": { + "start": 525, + "end": 560, + "ctxt": 0 + }, + "body": null, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 551, + "end": 559, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 553, + "end": 559, + "ctxt": 0 + }, + "kind": "string" + } + } + }, + "kind": "method", + "isStatic": false, + "accessibility": null, + "isAbstract": true, + "isOptional": false, + "isOverride": true + } + ], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] + } } ], "interpreter": null diff --git a/crates/swc_ecma_parser/tests/typescript/class/override/input.ts b/crates/swc_ecma_parser/tests/typescript/class/override/input.ts index 554c39ed3e41..a8fbf793a2bc 100644 --- a/crates/swc_ecma_parser/tests/typescript/class/override/input.ts +++ b/crates/swc_ecma_parser/tests/typescript/class/override/input.ts @@ -2,4 +2,10 @@ class C extends B { override prop = 5; override method() { } +} +// even without an extends it should set is_override +class C { + override prop = 5; + override method() { + } } \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/class/override/input.ts.json b/crates/swc_ecma_parser/tests/typescript/class/override/input.ts.json index 14b5ea575a4b..5a84f3fabb59 100644 --- a/crates/swc_ecma_parser/tests/typescript/class/override/input.ts.json +++ b/crates/swc_ecma_parser/tests/typescript/class/override/input.ts.json @@ -2,7 +2,7 @@ "type": "Script", "span": { "start": 1, - "end": 69, + "end": 181, "ctxt": 0 }, "body": [ @@ -125,6 +125,117 @@ "typeParams": null, "superTypeParams": null, "implements": [] + }, + { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 129, + "end": 130, + "ctxt": 0 + }, + "value": "C", + "optional": false + }, + "declare": false, + "span": { + "start": 123, + "end": 181, + "ctxt": 0 + }, + "decorators": [], + "body": [ + { + "type": "ClassProperty", + "span": { + "start": 135, + "end": 153, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 144, + "end": 148, + "ctxt": 0 + }, + "value": "prop", + "optional": false + }, + "value": { + "type": "NumericLiteral", + "span": { + "start": 151, + "end": 152, + "ctxt": 0 + }, + "value": 5.0, + "raw": "5" + }, + "typeAnnotation": null, + "isStatic": false, + "decorators": [], + "accessibility": null, + "isAbstract": false, + "isOptional": false, + "isOverride": true, + "readonly": false, + "declare": false, + "definite": false + }, + { + "type": "ClassMethod", + "span": { + "start": 156, + "end": 179, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 165, + "end": 171, + "ctxt": 0 + }, + "value": "method", + "optional": false + }, + "function": { + "params": [], + "decorators": [], + "span": { + "start": 156, + "end": 179, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 174, + "end": 179, + "ctxt": 0 + }, + "stmts": [] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + "kind": "method", + "isStatic": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false, + "isOverride": true + } + ], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] } ], "interpreter": null