diff --git a/crates/rome_js_parser/src/syntax/function.rs b/crates/rome_js_parser/src/syntax/function.rs index 9bc8e31c8a2..a55664fb363 100644 --- a/crates/rome_js_parser/src/syntax/function.rs +++ b/crates/rome_js_parser/src/syntax/function.rs @@ -116,6 +116,10 @@ pub(super) fn parse_function_expression(p: &mut Parser) -> ParsedSyntax { // test ts ts_export_default_function_overload // export default function test(a: string): string; // export default function test(a: string | undefined): string { return "hello" } +// +// test ts ts_export_function_overload +// export function test(a: string): string; +// export function test(a: string | undefined): string { return "hello" } pub(super) fn parse_function_export_default_declaration(p: &mut Parser) -> ParsedSyntax { if !is_at_function(p) { return Absent; @@ -153,6 +157,10 @@ enum FunctionKind { } impl FunctionKind { + const fn is_export_default(&self) -> bool { + matches!(self, FunctionKind::ExportDefault) + } + fn is_id_optional(&self) -> bool { matches!(self, FunctionKind::Expression | FunctionKind::ExportDefault) } @@ -276,7 +284,11 @@ fn parse_function(p: &mut Parser, m: Marker, kind: FunctionKind) -> CompletedMar )); } - m.complete(p, TS_DECLARE_FUNCTION_DECLARATION) + if kind.is_export_default() { + m.complete(p, TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION) + } else { + m.complete(p, TS_DECLARE_FUNCTION_DECLARATION) + } } else { body.or_add_diagnostic(p, js_parse_error::expected_function_body); diff --git a/crates/rome_js_parser/src/syntax/module.rs b/crates/rome_js_parser/src/syntax/module.rs index 94f5d905200..7c4d00d462e 100644 --- a/crates/rome_js_parser/src/syntax/module.rs +++ b/crates/rome_js_parser/src/syntax/module.rs @@ -1193,9 +1193,10 @@ fn parse_export_default_declaration_clause( }; let item_kind = match (kind, declaration.kind()) { - (ExportDefaultDeclarationKind::Function, Some(TS_DECLARE_FUNCTION_DECLARATION)) => { - ExportDefaultItemKind::FunctionOverload - } + ( + ExportDefaultDeclarationKind::Function, + Some(TS_DECLARE_FUNCTION_DECLARATION | TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION), + ) => ExportDefaultItemKind::FunctionOverload, (ExportDefaultDeclarationKind::Function, _) => ExportDefaultItemKind::FunctionDeclaration, (ExportDefaultDeclarationKind::Interface, _) => ExportDefaultItemKind::Interface, _ => ExportDefaultItemKind::Declaration, diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_export_default_function_overload.rast b/crates/rome_js_parser/test_data/inline/ok/ts_export_default_function_overload.rast index 6cc00f75280..55b7229818a 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_export_default_function_overload.rast +++ b/crates/rome_js_parser/test_data/inline/ok/ts_export_default_function_overload.rast @@ -6,7 +6,7 @@ JsModule { export_token: EXPORT_KW@0..7 "export" [] [Whitespace(" ")], export_clause: JsExportDefaultDeclarationClause { default_token: DEFAULT_KW@7..15 "default" [] [Whitespace(" ")], - declaration: TsDeclareFunctionDeclaration { + declaration: TsDeclareFunctionExportDefaultDeclaration { async_token: missing (optional), function_token: FUNCTION_KW@15..24 "function" [] [Whitespace(" ")], id: JsIdentifierBinding { @@ -119,7 +119,7 @@ JsModule { 0: EXPORT_KW@0..7 "export" [] [Whitespace(" ")] 1: JS_EXPORT_DEFAULT_DECLARATION_CLAUSE@7..48 0: DEFAULT_KW@7..15 "default" [] [Whitespace(" ")] - 1: TS_DECLARE_FUNCTION_DECLARATION@15..48 + 1: TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION@15..48 0: (empty) 1: FUNCTION_KW@15..24 "function" [] [Whitespace(" ")] 2: JS_IDENTIFIER_BINDING@24..28 diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.rast b/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.rast new file mode 100644 index 00000000000..220f8c3076f --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.rast @@ -0,0 +1,178 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsExport { + export_token: EXPORT_KW@0..7 "export" [] [Whitespace(" ")], + export_clause: TsDeclareFunctionDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@7..16 "function" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@16..20 "test" [] [], + }, + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@20..21 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@21..22 "a" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@22..24 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@24..30 "string" [] [], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@30..31 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@31..33 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@33..39 "string" [] [], + }, + }, + semicolon_token: SEMICOLON@39..40 ";" [] [], + }, + }, + JsExport { + export_token: EXPORT_KW@40..48 "export" [Newline("\n")] [Whitespace(" ")], + export_clause: JsFunctionDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@48..57 "function" [] [Whitespace(" ")], + star_token: missing (optional), + id: JsIdentifierBinding { + name_token: IDENT@57..61 "test" [] [], + }, + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@61..62 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@62..63 "a" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@63..65 ":" [] [Whitespace(" ")], + ty: TsUnionType { + leading_separator_token: missing (optional), + types: TsUnionTypeVariantList [ + TsStringType { + string_token: STRING_KW@65..72 "string" [] [Whitespace(" ")], + }, + PIPE@72..74 "|" [] [Whitespace(" ")], + TsUndefinedType { + undefined_token: UNDEFINED_KW@74..83 "undefined" [] [], + }, + ], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@83..84 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@84..86 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@86..93 "string" [] [Whitespace(" ")], + }, + }, + body: JsFunctionBody { + l_curly_token: L_CURLY@93..95 "{" [] [Whitespace(" ")], + directives: JsDirectiveList [], + statements: JsStatementList [ + JsReturnStatement { + return_token: RETURN_KW@95..102 "return" [] [Whitespace(" ")], + argument: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@102..110 "\"hello\"" [] [Whitespace(" ")], + }, + semicolon_token: missing (optional), + }, + ], + r_curly_token: R_CURLY@110..111 "}" [] [], + }, + }, + }, + ], + eof_token: EOF@111..112 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..112 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..111 + 0: JS_EXPORT@0..40 + 0: EXPORT_KW@0..7 "export" [] [Whitespace(" ")] + 1: TS_DECLARE_FUNCTION_DECLARATION@7..40 + 0: (empty) + 1: FUNCTION_KW@7..16 "function" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@16..20 + 0: IDENT@16..20 "test" [] [] + 3: (empty) + 4: JS_PARAMETERS@20..31 + 0: L_PAREN@20..21 "(" [] [] + 1: JS_PARAMETER_LIST@21..30 + 0: JS_FORMAL_PARAMETER@21..30 + 0: JS_IDENTIFIER_BINDING@21..22 + 0: IDENT@21..22 "a" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@22..30 + 0: COLON@22..24 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@24..30 + 0: STRING_KW@24..30 "string" [] [] + 3: (empty) + 2: R_PAREN@30..31 ")" [] [] + 5: TS_RETURN_TYPE_ANNOTATION@31..39 + 0: COLON@31..33 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@33..39 + 0: STRING_KW@33..39 "string" [] [] + 6: SEMICOLON@39..40 ";" [] [] + 1: JS_EXPORT@40..111 + 0: EXPORT_KW@40..48 "export" [Newline("\n")] [Whitespace(" ")] + 1: JS_FUNCTION_DECLARATION@48..111 + 0: (empty) + 1: FUNCTION_KW@48..57 "function" [] [Whitespace(" ")] + 2: (empty) + 3: JS_IDENTIFIER_BINDING@57..61 + 0: IDENT@57..61 "test" [] [] + 4: (empty) + 5: JS_PARAMETERS@61..84 + 0: L_PAREN@61..62 "(" [] [] + 1: JS_PARAMETER_LIST@62..83 + 0: JS_FORMAL_PARAMETER@62..83 + 0: JS_IDENTIFIER_BINDING@62..63 + 0: IDENT@62..63 "a" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@63..83 + 0: COLON@63..65 ":" [] [Whitespace(" ")] + 1: TS_UNION_TYPE@65..83 + 0: (empty) + 1: TS_UNION_TYPE_VARIANT_LIST@65..83 + 0: TS_STRING_TYPE@65..72 + 0: STRING_KW@65..72 "string" [] [Whitespace(" ")] + 1: PIPE@72..74 "|" [] [Whitespace(" ")] + 2: TS_UNDEFINED_TYPE@74..83 + 0: UNDEFINED_KW@74..83 "undefined" [] [] + 3: (empty) + 2: R_PAREN@83..84 ")" [] [] + 6: TS_RETURN_TYPE_ANNOTATION@84..93 + 0: COLON@84..86 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@86..93 + 0: STRING_KW@86..93 "string" [] [Whitespace(" ")] + 7: JS_FUNCTION_BODY@93..111 + 0: L_CURLY@93..95 "{" [] [Whitespace(" ")] + 1: JS_DIRECTIVE_LIST@95..95 + 2: JS_STATEMENT_LIST@95..110 + 0: JS_RETURN_STATEMENT@95..110 + 0: RETURN_KW@95..102 "return" [] [Whitespace(" ")] + 1: JS_STRING_LITERAL_EXPRESSION@102..110 + 0: JS_STRING_LITERAL@102..110 "\"hello\"" [] [Whitespace(" ")] + 2: (empty) + 3: R_CURLY@110..111 "}" [] [] + 3: EOF@111..112 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.ts b/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.ts new file mode 100644 index 00000000000..ac370b725d8 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_export_function_overload.ts @@ -0,0 +1,2 @@ +export function test(a: string): string; +export function test(a: string | undefined): string { return "hello" }