diff --git a/ecmascript/parser/src/parser/class_and_fn.rs b/ecmascript/parser/src/parser/class_and_fn.rs index ed884742db35..30c66d0ec2f5 100644 --- a/ecmascript/parser/src/parser/class_and_fn.rs +++ b/ecmascript/parser/src/parser/class_and_fn.rs @@ -295,9 +295,8 @@ impl<'a, I: Tokens> Parser<'a, I> { } fn parse_class_member(&mut self) -> PResult<'a, ClassMember> { - let decorators = self.parse_decorators(false)?; - let start = cur_pos!(); + let decorators = self.parse_decorators(false)?; if eat!("declare") { self.emit_err(self.input.prev_span(), SyntaxError::TS1031); @@ -364,19 +363,18 @@ impl<'a, I: Tokens> Parser<'a, I> { } } - self.parse_class_member_with_is_static(accessibility, static_token, decorators) + self.parse_class_member_with_is_static(start, accessibility, static_token, decorators) } #[allow(clippy::cognitive_complexity)] fn parse_class_member_with_is_static( &mut self, + start: BytePos, accessibility: Option, static_token: Option, decorators: Vec, ) -> PResult<'a, ClassMember> { let is_static = static_token.is_some(); - let start = static_token.map(|s| s.lo()).unwrap_or(cur_pos!()); - let modifier = self.parse_ts_modifier(&["abstract", "readonly"])?; let (is_abstract, readonly) = match modifier { Some("abstract") => (true, self.parse_ts_modifier(&["readonly"])?.is_some()), diff --git a/ecmascript/parser/src/parser/pat.rs b/ecmascript/parser/src/parser/pat.rs index 93f00f789596..54b311710029 100644 --- a/ecmascript/parser/src/parser/pat.rs +++ b/ecmascript/parser/src/parser/pat.rs @@ -275,9 +275,9 @@ impl<'a, I: Tokens> Parser<'a, I> { } fn parse_constructor_param(&mut self) -> PResult<'a, PatOrTsParamProp> { + let start = cur_pos!(); let decorators = self.parse_decorators(false)?; - let start = cur_pos!(); let (accessibility, readonly) = if self.input.syntax().typescript() { let accessibility = self.parse_access_modifier()?; ( @@ -290,16 +290,17 @@ impl<'a, I: Tokens> Parser<'a, I> { if accessibility == None && !readonly { self.parse_formal_param().map(PatOrTsParamProp::from) } else { + let param = match self.parse_formal_param()? { + Pat::Ident(i) => TsParamPropParam::Ident(i), + Pat::Assign(a) => TsParamPropParam::Assign(a), + node => syntax_error!(node.span(), SyntaxError::TsInvalidParamPropPat), + }; Ok(PatOrTsParamProp::TsParamProp(TsParamProp { span: span!(start), accessibility, readonly, decorators, - param: match self.parse_formal_param()? { - Pat::Ident(i) => TsParamPropParam::Ident(i), - Pat::Assign(a) => TsParamPropParam::Assign(a), - node => syntax_error!(node.span(), SyntaxError::TsInvalidParamPropPat), - }, + param, })) } } diff --git a/ecmascript/parser/src/parser/stmt.rs b/ecmascript/parser/src/parser/stmt.rs index f11df7bed251..c7124a8ba521 100644 --- a/ecmascript/parser/src/parser/stmt.rs +++ b/ecmascript/parser/src/parser/stmt.rs @@ -72,13 +72,14 @@ impl<'a, I: Tokens> Parser<'a, I> { Self: StmtLikeParser<'a, Type>, Type: IsDirective + From, { + let start = cur_pos!(); let decorators = self.parse_decorators(true)?; if is_one_of!("import", "export") { return self.handle_import_export(top_level, decorators); } - self.parse_stmt_internal(include_decl, top_level, decorators) + self.parse_stmt_internal(start, include_decl, top_level, decorators) .map(From::from) } @@ -86,12 +87,11 @@ impl<'a, I: Tokens> Parser<'a, I> { #[allow(clippy::cognitive_complexity)] fn parse_stmt_internal( &mut self, + start: BytePos, include_decl: bool, top_level: bool, decorators: Vec, ) -> PResult<'a, Stmt> { - let start = cur_pos!(); - if self.input.syntax().typescript() && is!("const") && peeked_is!("enum") { assert_and_bump!("const"); let _ = cur!(true)?; diff --git a/ecmascript/parser/tests/typescript/class/decorators/input.ts b/ecmascript/parser/tests/typescript/class/decorators/input.ts new file mode 100644 index 000000000000..8774991a1008 --- /dev/null +++ b/ecmascript/parser/tests/typescript/class/decorators/input.ts @@ -0,0 +1,18 @@ +@dec +class C { + constructor(@dec public param: string) { + } + + @dec + @dec2 + method() {} + + @dec + prop; + + @dec + get prop2() { return 5; } + + @dec + static method() {} +} diff --git a/ecmascript/parser/tests/typescript/class/decorators/input.ts.json b/ecmascript/parser/tests/typescript/class/decorators/input.ts.json new file mode 100644 index 000000000000..3fa5c109002e --- /dev/null +++ b/ecmascript/parser/tests/typescript/class/decorators/input.ts.json @@ -0,0 +1,433 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 196, + "ctxt": 0 + }, + "body": [ + { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 11, + "end": 12, + "ctxt": 0 + }, + "value": "C", + "typeAnnotation": null, + "optional": false + }, + "declare": false, + "span": { + "start": 0, + "end": 196, + "ctxt": 0 + }, + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 0, + "end": 4, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 1, + "end": 4, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + } + ], + "body": [ + { + "type": "Constructor", + "span": { + "start": 19, + "end": 65, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 19, + "end": 30, + "ctxt": 0 + }, + "value": "constructor", + "typeAnnotation": null, + "optional": false + }, + "params": [ + { + "type": "TsParameterProperty", + "span": { + "start": 31, + "end": 56, + "ctxt": 0 + }, + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 31, + "end": 35, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 32, + "end": 35, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + } + ], + "accessibility": "public", + "readonly": false, + "param": { + "type": "Identifier", + "span": { + "start": 43, + "end": 56, + "ctxt": 0 + }, + "value": "param", + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 48, + "end": 56, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 50, + "end": 56, + "ctxt": 0 + }, + "kind": "string" + } + }, + "optional": false + } + } + ], + "body": { + "type": "BlockStatement", + "span": { + "start": 58, + "end": 65, + "ctxt": 0 + }, + "stmts": [] + }, + "accessibility": null, + "isOptional": false + }, + { + "type": "ClassMethod", + "span": { + "start": 71, + "end": 101, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 90, + "end": 96, + "ctxt": 0 + }, + "value": "method", + "typeAnnotation": null, + "optional": false + }, + "function": { + "params": [], + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 71, + "end": 75, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 72, + "end": 75, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + }, + { + "type": "Decorator", + "span": { + "start": 80, + "end": 85, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 81, + "end": 85, + "ctxt": 0 + }, + "value": "dec2", + "typeAnnotation": null, + "optional": false + } + } + ], + "span": { + "start": 71, + "end": 101, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 99, + "end": 101, + "ctxt": 0 + }, + "stmts": [] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + "kind": "method", + "isStatic": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false + }, + { + "type": "ClassProperty", + "span": { + "start": 107, + "end": 121, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 116, + "end": 120, + "ctxt": 0 + }, + "value": "prop", + "typeAnnotation": null, + "optional": false + }, + "value": null, + "typeAnnotation": null, + "isStatic": false, + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 107, + "end": 111, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 108, + "end": 111, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + } + ], + "computed": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false, + "readonly": false, + "definite": false + }, + { + "type": "ClassMethod", + "span": { + "start": 127, + "end": 161, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 140, + "end": 145, + "ctxt": 0 + }, + "value": "prop2", + "typeAnnotation": null, + "optional": false + }, + "function": { + "params": [], + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 127, + "end": 131, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 128, + "end": 131, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + } + ], + "span": { + "start": 127, + "end": 161, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 148, + "end": 161, + "ctxt": 0 + }, + "stmts": [ + { + "type": "ReturnStatement", + "span": { + "start": 150, + "end": 159, + "ctxt": 0 + }, + "argument": { + "type": "NumericLiteral", + "span": { + "start": 157, + "end": 158, + "ctxt": 0 + }, + "value": 5.0 + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + "kind": "getter", + "isStatic": false, + "accessibility": null, + "isAbstract": false, + "isOptional": false + }, + { + "type": "ClassMethod", + "span": { + "start": 167, + "end": 194, + "ctxt": 0 + }, + "key": { + "type": "Identifier", + "span": { + "start": 183, + "end": 189, + "ctxt": 0 + }, + "value": "method", + "typeAnnotation": null, + "optional": false + }, + "function": { + "params": [], + "decorators": [ + { + "type": "Decorator", + "span": { + "start": 167, + "end": 171, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 168, + "end": 171, + "ctxt": 0 + }, + "value": "dec", + "typeAnnotation": null, + "optional": false + } + } + ], + "span": { + "start": 167, + "end": 194, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 192, + "end": 194, + "ctxt": 0 + }, + "stmts": [] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + "kind": "method", + "isStatic": true, + "accessibility": null, + "isAbstract": false, + "isOptional": false + } + ], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] + } + ], + "interpreter": null +} diff --git a/ecmascript/parser/tests/typescript/class/members-with-reserved-names/input.ts.json b/ecmascript/parser/tests/typescript/class/members-with-reserved-names/input.ts.json index 8b770961cdd7..3be5a2292dbd 100644 --- a/ecmascript/parser/tests/typescript/class/members-with-reserved-names/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/members-with-reserved-names/input.ts.json @@ -30,7 +30,7 @@ { "type": "ClassMethod", "span": { - "start": 21, + "start": 14, "end": 36, "ctxt": 0 }, @@ -49,7 +49,7 @@ "params": [], "decorators": [], "span": { - "start": 21, + "start": 14, "end": 36, "ctxt": 0 }, diff --git a/ecmascript/parser/tests/typescript/class/modifiers-accessors/input.ts.json b/ecmascript/parser/tests/typescript/class/modifiers-accessors/input.ts.json index 6e8cdee8a282..4d29b8b34234 100644 --- a/ecmascript/parser/tests/typescript/class/modifiers-accessors/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/modifiers-accessors/input.ts.json @@ -132,7 +132,7 @@ { "type": "ClassMethod", "span": { - "start": 125, + "start": 118, "end": 144, "ctxt": 0 }, @@ -151,7 +151,7 @@ "params": [], "decorators": [], "span": { - "start": 125, + "start": 118, "end": 144, "ctxt": 0 }, @@ -170,7 +170,7 @@ { "type": "ClassMethod", "span": { - "start": 156, + "start": 149, "end": 186, "ctxt": 0 }, @@ -189,7 +189,7 @@ "params": [], "decorators": [], "span": { - "start": 156, + "start": 149, "end": 186, "ctxt": 0 }, @@ -234,7 +234,7 @@ { "type": "ClassMethod", "span": { - "start": 199, + "start": 192, "end": 221, "ctxt": 0 }, @@ -253,7 +253,7 @@ "params": [], "decorators": [], "span": { - "start": 199, + "start": 192, "end": 221, "ctxt": 0 }, @@ -298,7 +298,7 @@ { "type": "ClassMethod", "span": { - "start": 236, + "start": 226, "end": 258, "ctxt": 0 }, @@ -317,7 +317,7 @@ "params": [], "decorators": [], "span": { - "start": 236, + "start": 226, "end": 258, "ctxt": 0 }, @@ -362,7 +362,7 @@ { "type": "ClassMethod", "span": { - "start": 271, + "start": 263, "end": 293, "ctxt": 0 }, @@ -381,7 +381,7 @@ "params": [], "decorators": [], "span": { - "start": 271, + "start": 263, "end": 293, "ctxt": 0 }, diff --git a/ecmascript/parser/tests/typescript/class/modifiers-methods-async/input.ts.json b/ecmascript/parser/tests/typescript/class/modifiers-methods-async/input.ts.json index 5297e980af1a..302fba896760 100644 --- a/ecmascript/parser/tests/typescript/class/modifiers-methods-async/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/modifiers-methods-async/input.ts.json @@ -114,7 +114,7 @@ { "type": "ClassMethod", "span": { - "start": 120, + "start": 113, "end": 141, "ctxt": 0 }, @@ -133,7 +133,7 @@ "params": [], "decorators": [], "span": { - "start": 120, + "start": 113, "end": 141, "ctxt": 0 }, @@ -152,7 +152,7 @@ { "type": "ClassMethod", "span": { - "start": 153, + "start": 146, "end": 174, "ctxt": 0 }, @@ -171,7 +171,7 @@ "params": [], "decorators": [], "span": { - "start": 153, + "start": 146, "end": 174, "ctxt": 0 }, @@ -198,7 +198,7 @@ { "type": "ClassMethod", "span": { - "start": 187, + "start": 180, "end": 200, "ctxt": 0 }, @@ -217,7 +217,7 @@ "params": [], "decorators": [], "span": { - "start": 187, + "start": 180, "end": 200, "ctxt": 0 }, @@ -244,7 +244,7 @@ { "type": "ClassMethod", "span": { - "start": 215, + "start": 205, "end": 228, "ctxt": 0 }, @@ -263,7 +263,7 @@ "params": [], "decorators": [], "span": { - "start": 215, + "start": 205, "end": 228, "ctxt": 0 }, @@ -290,7 +290,7 @@ { "type": "ClassMethod", "span": { - "start": 241, + "start": 233, "end": 254, "ctxt": 0 }, @@ -309,7 +309,7 @@ "params": [], "decorators": [], "span": { - "start": 241, + "start": 233, "end": 254, "ctxt": 0 }, diff --git a/ecmascript/parser/tests/typescript/class/modifiers-properties/input.ts.json b/ecmascript/parser/tests/typescript/class/modifiers-properties/input.ts.json index 3f890693bba8..88c36c905955 100644 --- a/ecmascript/parser/tests/typescript/class/modifiers-properties/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/modifiers-properties/input.ts.json @@ -162,7 +162,7 @@ { "type": "ClassProperty", "span": { - "start": 103, + "start": 96, "end": 106, "ctxt": 0 }, @@ -191,7 +191,7 @@ { "type": "ClassProperty", "span": { - "start": 121, + "start": 111, "end": 124, "ctxt": 0 }, @@ -220,7 +220,7 @@ { "type": "ClassProperty", "span": { - "start": 137, + "start": 129, "end": 140, "ctxt": 0 }, @@ -336,7 +336,7 @@ { "type": "ClassProperty", "span": { - "start": 230, + "start": 223, "end": 243, "ctxt": 0 }, @@ -365,7 +365,7 @@ { "type": "ClassProperty", "span": { - "start": 255, + "start": 248, "end": 268, "ctxt": 0 }, @@ -394,7 +394,7 @@ { "type": "ClassProperty", "span": { - "start": 280, + "start": 273, "end": 291, "ctxt": 0 }, @@ -423,7 +423,7 @@ { "type": "ClassProperty", "span": { - "start": 303, + "start": 296, "end": 326, "ctxt": 0 }, @@ -452,7 +452,7 @@ { "type": "ClassProperty", "span": { - "start": 338, + "start": 331, "end": 361, "ctxt": 0 }, @@ -481,7 +481,7 @@ { "type": "ClassProperty", "span": { - "start": 373, + "start": 366, "end": 394, "ctxt": 0 }, diff --git a/ecmascript/parser/tests/typescript/class/parameter-properties/input.ts.json b/ecmascript/parser/tests/typescript/class/parameter-properties/input.ts.json index 624bf6d3c074..07236249f861 100644 --- a/ecmascript/parser/tests/typescript/class/parameter-properties/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/parameter-properties/input.ts.json @@ -50,7 +50,7 @@ "type": "TsParameterProperty", "span": { "start": 35, - "end": 43, + "end": 45, "ctxt": 0 }, "decorators": [], @@ -72,7 +72,7 @@ "type": "TsParameterProperty", "span": { "start": 55, - "end": 61, + "end": 72, "ctxt": 0 }, "decorators": [], @@ -110,7 +110,7 @@ "type": "TsParameterProperty", "span": { "start": 82, - "end": 91, + "end": 95, "ctxt": 0 }, "decorators": [], @@ -132,7 +132,7 @@ "type": "TsParameterProperty", "span": { "start": 105, - "end": 112, + "end": 124, "ctxt": 0 }, "decorators": [], @@ -170,7 +170,7 @@ "type": "TsParameterProperty", "span": { "start": 134, - "end": 149, + "end": 153, "ctxt": 0 }, "decorators": [], @@ -192,7 +192,7 @@ "type": "TsParameterProperty", "span": { "start": 206, - "end": 214, + "end": 220, "ctxt": 0 }, "decorators": [], @@ -232,7 +232,7 @@ "type": "TsParameterProperty", "span": { "start": 230, - "end": 236, + "end": 251, "ctxt": 0 }, "decorators": [], diff --git a/ecmascript/parser/tests/typescript/class/static/input.ts.json b/ecmascript/parser/tests/typescript/class/static/input.ts.json index 288b8a2309a0..684d328177ad 100644 --- a/ecmascript/parser/tests/typescript/class/static/input.ts.json +++ b/ecmascript/parser/tests/typescript/class/static/input.ts.json @@ -68,7 +68,7 @@ { "type": "ClassMethod", "span": { - "start": 37, + "start": 30, "end": 48, "ctxt": 0 }, @@ -87,7 +87,7 @@ "params": [], "decorators": [], "span": { - "start": 37, + "start": 30, "end": 48, "ctxt": 0 }, @@ -106,7 +106,7 @@ { "type": "ClassMethod", "span": { - "start": 63, + "start": 53, "end": 74, "ctxt": 0 }, @@ -125,7 +125,7 @@ "params": [], "decorators": [], "span": { - "start": 63, + "start": 53, "end": 74, "ctxt": 0 }, @@ -144,7 +144,7 @@ { "type": "ClassMethod", "span": { - "start": 87, + "start": 79, "end": 98, "ctxt": 0 }, @@ -163,7 +163,7 @@ "params": [], "decorators": [], "span": { - "start": 87, + "start": 79, "end": 98, "ctxt": 0 }, diff --git a/ecmascript/parser/tests/typescript/decorators/type-arguments/input.ts.json b/ecmascript/parser/tests/typescript/decorators/type-arguments/input.ts.json index 6ccff4987b94..8537491e72b2 100644 --- a/ecmascript/parser/tests/typescript/decorators/type-arguments/input.ts.json +++ b/ecmascript/parser/tests/typescript/decorators/type-arguments/input.ts.json @@ -21,7 +21,7 @@ }, "declare": false, "span": { - "start": 21, + "start": 0, "end": 34, "ctxt": 0 },