diff --git a/crates/rome_js_factory/src/generated/node_factory.rs b/crates/rome_js_factory/src/generated/node_factory.rs index 9d617aa2ee9..a92c7700707 100644 --- a/crates/rome_js_factory/src/generated/node_factory.rs +++ b/crates/rome_js_factory/src/generated/node_factory.rs @@ -4247,6 +4247,72 @@ impl TsDeclareFunctionDeclarationBuilder { )) } } +pub fn ts_declare_function_export_default_declaration( + function_token: SyntaxToken, + parameters: JsParameters, +) -> TsDeclareFunctionExportDefaultDeclarationBuilder { + TsDeclareFunctionExportDefaultDeclarationBuilder { + function_token, + parameters, + async_token: None, + id: None, + type_parameters: None, + return_type_annotation: None, + semicolon_token: None, + } +} +pub struct TsDeclareFunctionExportDefaultDeclarationBuilder { + function_token: SyntaxToken, + parameters: JsParameters, + async_token: Option, + id: Option, + type_parameters: Option, + return_type_annotation: Option, + semicolon_token: Option, +} +impl TsDeclareFunctionExportDefaultDeclarationBuilder { + pub fn with_async_token(mut self, async_token: SyntaxToken) -> Self { + self.async_token = Some(async_token); + self + } + pub fn with_id(mut self, id: JsAnyBinding) -> Self { + self.id = Some(id); + self + } + pub fn with_type_parameters(mut self, type_parameters: TsTypeParameters) -> Self { + self.type_parameters = Some(type_parameters); + self + } + pub fn with_return_type_annotation( + mut self, + return_type_annotation: TsReturnTypeAnnotation, + ) -> Self { + self.return_type_annotation = Some(return_type_annotation); + self + } + pub fn with_semicolon_token(mut self, semicolon_token: SyntaxToken) -> Self { + self.semicolon_token = Some(semicolon_token); + self + } + pub fn build(self) -> TsDeclareFunctionExportDefaultDeclaration { + TsDeclareFunctionExportDefaultDeclaration::unwrap_cast(SyntaxNode::new_detached( + JsSyntaxKind::TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION, + [ + self.async_token.map(|token| SyntaxElement::Token(token)), + Some(SyntaxElement::Token(self.function_token)), + self.id + .map(|token| SyntaxElement::Node(token.into_syntax())), + self.type_parameters + .map(|token| SyntaxElement::Node(token.into_syntax())), + Some(SyntaxElement::Node(self.parameters.into_syntax())), + self.return_type_annotation + .map(|token| SyntaxElement::Node(token.into_syntax())), + self.semicolon_token + .map(|token| SyntaxElement::Token(token)), + ], + )) + } +} pub fn ts_declare_modifier(modifier_token: SyntaxToken) -> TsDeclareModifier { TsDeclareModifier::unwrap_cast(SyntaxNode::new_detached( JsSyntaxKind::TS_DECLARE_MODIFIER, diff --git a/crates/rome_js_factory/src/generated/syntax_factory.rs b/crates/rome_js_factory/src/generated/syntax_factory.rs index e0033f74b61..53f6f1ae28d 100644 --- a/crates/rome_js_factory/src/generated/syntax_factory.rs +++ b/crates/rome_js_factory/src/generated/syntax_factory.rs @@ -6562,6 +6562,67 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.into_node(TS_DECLARE_FUNCTION_DECLARATION, children) } + TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION => { + let mut elements = (&children).into_iter(); + let mut slots: RawNodeSlots<7usize> = RawNodeSlots::default(); + let mut current_element = elements.next(); + if let Some(element) = ¤t_element { + if element.kind() == T![async] { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if element.kind() == T![function] { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if JsAnyBinding::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if TsTypeParameters::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if JsParameters::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if TsReturnTypeAnnotation::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if element.kind() == T ! [;] { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if current_element.is_some() { + return RawSyntaxNode::new( + TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION.to_unknown(), + children.into_iter().map(Some), + ); + } + slots.into_node(TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION, children) + } TS_DECLARE_MODIFIER => { let mut elements = (&children).into_iter(); let mut slots: RawNodeSlots<1usize> = RawNodeSlots::default(); diff --git a/crates/rome_js_formatter/src/generated.rs b/crates/rome_js_formatter/src/generated.rs index a138e38fd71..8f9d683c1cb 100644 --- a/crates/rome_js_formatter/src/generated.rs +++ b/crates/rome_js_formatter/src/generated.rs @@ -6318,6 +6318,21 @@ impl IntoFormat for rome_js_syntax::JsFunctionExportDefa FormatOwnedWithRule :: new (self , crate :: js :: declarations :: function_export_default_declaration :: FormatJsFunctionExportDefaultDeclaration :: default ()) } } +impl FormatRule < rome_js_syntax :: TsDeclareFunctionExportDefaultDeclaration > for crate :: ts :: declarations :: declare_function_export_default_declaration :: FormatTsDeclareFunctionExportDefaultDeclaration { type Context = JsFormatContext ; # [inline (always)] fn fmt (& self , node : & rome_js_syntax :: TsDeclareFunctionExportDefaultDeclaration , f : & mut JsFormatter) -> FormatResult < () > { FormatNodeRule :: < rome_js_syntax :: TsDeclareFunctionExportDefaultDeclaration > :: fmt (self , node , f) } } +impl AsFormat for rome_js_syntax::TsDeclareFunctionExportDefaultDeclaration { + type Format < 'a > = FormatRefWithRule < 'a , rome_js_syntax :: TsDeclareFunctionExportDefaultDeclaration , crate :: ts :: declarations :: declare_function_export_default_declaration :: FormatTsDeclareFunctionExportDefaultDeclaration > ; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule :: new (self , crate :: ts :: declarations :: declare_function_export_default_declaration :: FormatTsDeclareFunctionExportDefaultDeclaration :: default ()) + } +} +impl IntoFormat + for rome_js_syntax::TsDeclareFunctionExportDefaultDeclaration +{ + type Format = FormatOwnedWithRule < rome_js_syntax :: TsDeclareFunctionExportDefaultDeclaration , crate :: ts :: declarations :: declare_function_export_default_declaration :: FormatTsDeclareFunctionExportDefaultDeclaration > ; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule :: new (self , crate :: ts :: declarations :: declare_function_export_default_declaration :: FormatTsDeclareFunctionExportDefaultDeclaration :: default ()) + } +} impl FormatRule for crate::js::module::export_named_shorthand_specifier::FormatJsExportNamedShorthandSpecifier { diff --git a/crates/rome_js_formatter/src/js/any/export_default_declaration.rs b/crates/rome_js_formatter/src/js/any/export_default_declaration.rs index f14680bf85e..c6cf290e0ca 100644 --- a/crates/rome_js_formatter/src/js/any/export_default_declaration.rs +++ b/crates/rome_js_formatter/src/js/any/export_default_declaration.rs @@ -14,10 +14,10 @@ impl FormatRule for FormatJsAnyExportDefaultDecla JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(node) => { node.format().fmt(f) } - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(node) => { + JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(node) => node.format().fmt(f), + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(node) => { node.format().fmt(f) } - JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(node) => node.format().fmt(f), } } } diff --git a/crates/rome_js_formatter/src/js/declarations/function_declaration.rs b/crates/rome_js_formatter/src/js/declarations/function_declaration.rs index c9abc172bc6..9b67e46584d 100644 --- a/crates/rome_js_formatter/src/js/declarations/function_declaration.rs +++ b/crates/rome_js_formatter/src/js/declarations/function_declaration.rs @@ -6,7 +6,8 @@ use rome_formatter::{write, RemoveSoftLinesBuffer}; use rome_js_syntax::{ JsAnyBinding, JsFunctionBody, JsFunctionDeclaration, JsFunctionExportDefaultDeclaration, JsFunctionExpression, JsParameters, JsSyntaxToken, TsAnyReturnType, - TsDeclareFunctionDeclaration, TsReturnTypeAnnotation, TsType, TsTypeParameters, + TsDeclareFunctionDeclaration, TsDeclareFunctionExportDefaultDeclaration, + TsReturnTypeAnnotation, TsType, TsTypeParameters, }; use rome_rowan::{declare_node_union, SyntaxResult}; @@ -24,7 +25,8 @@ declare_node_union! { JsFunctionDeclaration | JsFunctionExpression | JsFunctionExportDefaultDeclaration | - TsDeclareFunctionDeclaration + TsDeclareFunctionDeclaration | + TsDeclareFunctionExportDefaultDeclaration } #[derive(Copy, Clone, Debug, Default)] @@ -42,6 +44,9 @@ impl FormatFunction { declaration.async_token() } FormatFunction::TsDeclareFunctionDeclaration(member) => member.async_token(), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => { + member.async_token() + } } } @@ -53,6 +58,9 @@ impl FormatFunction { declaration.function_token() } FormatFunction::TsDeclareFunctionDeclaration(member) => member.function_token(), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => { + member.function_token() + } } } @@ -64,6 +72,7 @@ impl FormatFunction { declaration.star_token() } FormatFunction::TsDeclareFunctionDeclaration(_) => None, + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(_) => None, } } @@ -73,6 +82,7 @@ impl FormatFunction { FormatFunction::JsFunctionExpression(expression) => Ok(expression.id()), FormatFunction::JsFunctionExportDefaultDeclaration(declaration) => Ok(declaration.id()), FormatFunction::TsDeclareFunctionDeclaration(member) => member.id().map(Some), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => Ok(member.id()), } } @@ -84,6 +94,9 @@ impl FormatFunction { declaration.type_parameters() } FormatFunction::TsDeclareFunctionDeclaration(member) => member.type_parameters(), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => { + member.type_parameters() + } } } @@ -95,6 +108,9 @@ impl FormatFunction { declaration.parameters() } FormatFunction::TsDeclareFunctionDeclaration(member) => member.parameters(), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => { + member.parameters() + } } } @@ -108,6 +124,9 @@ impl FormatFunction { declaration.return_type_annotation() } FormatFunction::TsDeclareFunctionDeclaration(member) => member.return_type_annotation(), + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(member) => { + member.return_type_annotation() + } } } @@ -119,6 +138,7 @@ impl FormatFunction { Some(declaration.body()?) } FormatFunction::TsDeclareFunctionDeclaration(_) => None, + FormatFunction::TsDeclareFunctionExportDefaultDeclaration(_) => None, }) } diff --git a/crates/rome_js_formatter/src/lib.rs b/crates/rome_js_formatter/src/lib.rs index a33b3df6302..e6819bd2f23 100644 --- a/crates/rome_js_formatter/src/lib.rs +++ b/crates/rome_js_formatter/src/lib.rs @@ -787,17 +787,9 @@ function() { // use this test check if your snippet prints as you wish, without using a snapshot fn quick_test() { let src = r#" -// different output than prettier -function Component4() { - - return ( -
- {fn(datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata)}{' '} -
-
- ); +declare module 'x' { + export default function (option: any): void } - "#; let syntax = SourceType::tsx(); let tree = parse(src, FileId::zero(), syntax); diff --git a/crates/rome_js_formatter/src/ts/declarations/declare_function_export_default_declaration.rs b/crates/rome_js_formatter/src/ts/declarations/declare_function_export_default_declaration.rs new file mode 100644 index 00000000000..997826993fe --- /dev/null +++ b/crates/rome_js_formatter/src/ts/declarations/declare_function_export_default_declaration.rs @@ -0,0 +1,25 @@ +use crate::js::declarations::function_declaration::FormatFunction; +use crate::prelude::*; +use crate::utils::FormatStatementSemicolon; +use rome_formatter::write; +use rome_js_syntax::TsDeclareFunctionExportDefaultDeclaration; + +#[derive(Debug, Clone, Default)] +pub struct FormatTsDeclareFunctionExportDefaultDeclaration; +impl FormatNodeRule + for FormatTsDeclareFunctionExportDefaultDeclaration +{ + fn fmt_fields( + &self, + node: &TsDeclareFunctionExportDefaultDeclaration, + f: &mut JsFormatter, + ) -> FormatResult<()> { + write![ + f, + [ + FormatFunction::from(node.clone()), + FormatStatementSemicolon::new(node.semicolon_token().as_ref()) + ] + ] + } +} diff --git a/crates/rome_js_formatter/src/ts/declarations/mod.rs b/crates/rome_js_formatter/src/ts/declarations/mod.rs index e26f1349a68..b14c0c723fc 100644 --- a/crates/rome_js_formatter/src/ts/declarations/mod.rs +++ b/crates/rome_js_formatter/src/ts/declarations/mod.rs @@ -1,6 +1,7 @@ //! Generated file, do not edit by hand, see `xtask/codegen` pub(crate) mod declare_function_declaration; +pub(crate) mod declare_function_export_default_declaration; pub(crate) mod enum_declaration; pub(crate) mod external_module_declaration; pub(crate) mod global_declaration; diff --git a/crates/rome_js_parser/src/syntax/function.rs b/crates/rome_js_parser/src/syntax/function.rs index beb7aedde80..a55664fb363 100644 --- a/crates/rome_js_parser/src/syntax/function.rs +++ b/crates/rome_js_parser/src/syntax/function.rs @@ -67,7 +67,7 @@ pub(super) fn parse_function_declaration( let m = p.start(); let mut function = if p.state.in_ambient_context() { - parse_ambient_function(p, m) + parse_ambient_function(p, m, AmbientFunctionKind::Declaration) } else { parse_function( p, @@ -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; @@ -124,12 +128,24 @@ pub(super) fn parse_function_export_default_declaration(p: &mut Parser) -> Parse let m = p.start(); Present(if p.state.in_ambient_context() { - parse_ambient_function(p, m) + parse_ambient_function(p, m, AmbientFunctionKind::ExportDefault) } else { parse_function(p, m, FunctionKind::ExportDefault) }) } +#[derive(PartialEq, Eq, Debug, Copy, Clone)] +enum AmbientFunctionKind { + Declaration, + ExportDefault, +} + +impl AmbientFunctionKind { + const fn is_export_default(&self) -> bool { + matches!(self, AmbientFunctionKind::ExportDefault) + } +} + #[derive(PartialEq, Eq, Debug, Copy, Clone)] enum FunctionKind { Declaration { @@ -141,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) } @@ -264,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); @@ -344,7 +368,7 @@ fn parse_function_id(p: &mut Parser, kind: FunctionKind, flags: SignatureFlags) // declare module a { // function test(): string; // } -pub(crate) fn parse_ambient_function(p: &mut Parser, m: Marker) -> CompletedMarker { +fn parse_ambient_function(p: &mut Parser, m: Marker, kind: AmbientFunctionKind) -> CompletedMarker { let stmt_start = p.cur_range().start(); // test_err ts ts_declare_async_function @@ -359,7 +383,17 @@ pub(crate) fn parse_ambient_function(p: &mut Parser, m: Marker) -> CompletedMark } p.expect(T![function]); - parse_binding(p).or_add_diagnostic(p, expected_binding); + let binding = parse_binding(p); + let is_binding_absent = binding.is_absent(); + + if !kind.is_export_default() && is_binding_absent { + // test_err ts ts_declare_function_export_declaration_missing_id + // declare module 'x' { + // export function(option: any): void + // } + binding.or_add_diagnostic(p, expected_binding); + } + parse_ts_type_parameters(p).ok(); parse_parameter_list(p, ParameterContext::Declaration, SignatureFlags::empty()) .or_add_diagnostic(p, expected_parameters); @@ -379,7 +413,20 @@ pub(crate) fn parse_ambient_function(p: &mut Parser, m: Marker) -> CompletedMark if is_async { m.complete(p, JS_UNKNOWN_STATEMENT) + } else if kind.is_export_default() { + // test ts ts_declare_function_export_default_declaration + // declare module 'x' { + // export default function(option: any): void + // } + // declare module 'y' { + // export default function test(option: any): void + // } + m.complete(p, TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION) } else { + // test ts ts_declare_function_export_declaration + // declare module 'x' { + // export function test(option: any): void + // } m.complete(p, TS_DECLARE_FUNCTION_DECLARATION) } } 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/err/ts_declare_function_export_declaration_missing_id.rast b/crates/rome_js_parser/test_data/inline/err/ts_declare_function_export_declaration_missing_id.rast new file mode 100644 index 00000000000..b4d0fcbec26 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_declare_function_export_declaration_missing_id.rast @@ -0,0 +1,121 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + TsDeclareStatement { + declare_token: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")], + declaration: TsExternalModuleDeclaration { + module_token: MODULE_KW@8..15 "module" [] [Whitespace(" ")], + source: JsModuleSource { + value_token: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")], + }, + body: TsModuleBlock { + l_curly_token: L_CURLY@19..20 "{" [] [], + items: JsModuleItemList [ + JsExport { + export_token: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + export_clause: TsDeclareFunctionDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@30..38 "function" [] [], + id: missing (required), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@38..39 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@39..45 "option" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@45..47 ":" [] [Whitespace(" ")], + ty: TsAnyType { + any_token: ANY_KW@47..50 "any" [] [], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@50..51 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@51..53 ":" [] [Whitespace(" ")], + ty: TsVoidType { + void_token: VOID_KW@53..57 "void" [] [], + }, + }, + semicolon_token: missing (optional), + }, + }, + ], + r_curly_token: R_CURLY@57..59 "}" [Newline("\n")] [], + }, + }, + }, + ], + eof_token: EOF@59..60 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..60 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..59 + 0: TS_DECLARE_STATEMENT@0..59 + 0: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")] + 1: TS_EXTERNAL_MODULE_DECLARATION@8..59 + 0: MODULE_KW@8..15 "module" [] [Whitespace(" ")] + 1: JS_MODULE_SOURCE@15..19 + 0: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")] + 2: TS_MODULE_BLOCK@19..59 + 0: L_CURLY@19..20 "{" [] [] + 1: JS_MODULE_ITEM_LIST@20..57 + 0: JS_EXPORT@20..57 + 0: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: TS_DECLARE_FUNCTION_DECLARATION@30..57 + 0: (empty) + 1: FUNCTION_KW@30..38 "function" [] [] + 2: (empty) + 3: (empty) + 4: JS_PARAMETERS@38..51 + 0: L_PAREN@38..39 "(" [] [] + 1: JS_PARAMETER_LIST@39..50 + 0: JS_FORMAL_PARAMETER@39..50 + 0: JS_IDENTIFIER_BINDING@39..45 + 0: IDENT@39..45 "option" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@45..50 + 0: COLON@45..47 ":" [] [Whitespace(" ")] + 1: TS_ANY_TYPE@47..50 + 0: ANY_KW@47..50 "any" [] [] + 3: (empty) + 2: R_PAREN@50..51 ")" [] [] + 5: TS_RETURN_TYPE_ANNOTATION@51..57 + 0: COLON@51..53 ":" [] [Whitespace(" ")] + 1: TS_VOID_TYPE@53..57 + 0: VOID_KW@53..57 "void" [] [] + 6: (empty) + 2: R_CURLY@57..59 "}" [Newline("\n")] [] + 3: EOF@59..60 "" [Newline("\n")] [] +-- +ts_declare_function_export_declaration_missing_id.ts:2:18 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected an identifier, an array pattern, or an object pattern but instead found '(' + + 1 │ declare module 'x' { + > 2 │ export function(option: any): void + │ ^ + 3 │ } + 4 │ + + i Expected an identifier, an array pattern, or an object pattern here + + 1 │ declare module 'x' { + > 2 │ export function(option: any): void + │ ^ + 3 │ } + 4 │ + +-- +declare module 'x' { + export function(option: any): void +} diff --git a/crates/rome_js_parser/test_data/inline/err/ts_declare_function_export_declaration_missing_id.ts b/crates/rome_js_parser/test_data/inline/err/ts_declare_function_export_declaration_missing_id.ts new file mode 100644 index 00000000000..6bd7906b376 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_declare_function_export_declaration_missing_id.ts @@ -0,0 +1,3 @@ +declare module 'x' { + export function(option: any): void +} diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.rast b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.rast new file mode 100644 index 00000000000..8932c041f9b --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.rast @@ -0,0 +1,101 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + TsDeclareStatement { + declare_token: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")], + declaration: TsExternalModuleDeclaration { + module_token: MODULE_KW@8..15 "module" [] [Whitespace(" ")], + source: JsModuleSource { + value_token: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")], + }, + body: TsModuleBlock { + l_curly_token: L_CURLY@19..20 "{" [] [], + items: JsModuleItemList [ + JsExport { + export_token: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + export_clause: TsDeclareFunctionDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@30..39 "function" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@39..43 "test" [] [], + }, + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@43..44 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@44..50 "option" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@50..52 ":" [] [Whitespace(" ")], + ty: TsAnyType { + any_token: ANY_KW@52..55 "any" [] [], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@55..56 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@56..58 ":" [] [Whitespace(" ")], + ty: TsVoidType { + void_token: VOID_KW@58..62 "void" [] [], + }, + }, + semicolon_token: missing (optional), + }, + }, + ], + r_curly_token: R_CURLY@62..64 "}" [Newline("\n")] [], + }, + }, + }, + ], + eof_token: EOF@64..65 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..65 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..64 + 0: TS_DECLARE_STATEMENT@0..64 + 0: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")] + 1: TS_EXTERNAL_MODULE_DECLARATION@8..64 + 0: MODULE_KW@8..15 "module" [] [Whitespace(" ")] + 1: JS_MODULE_SOURCE@15..19 + 0: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")] + 2: TS_MODULE_BLOCK@19..64 + 0: L_CURLY@19..20 "{" [] [] + 1: JS_MODULE_ITEM_LIST@20..62 + 0: JS_EXPORT@20..62 + 0: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: TS_DECLARE_FUNCTION_DECLARATION@30..62 + 0: (empty) + 1: FUNCTION_KW@30..39 "function" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@39..43 + 0: IDENT@39..43 "test" [] [] + 3: (empty) + 4: JS_PARAMETERS@43..56 + 0: L_PAREN@43..44 "(" [] [] + 1: JS_PARAMETER_LIST@44..55 + 0: JS_FORMAL_PARAMETER@44..55 + 0: JS_IDENTIFIER_BINDING@44..50 + 0: IDENT@44..50 "option" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@50..55 + 0: COLON@50..52 ":" [] [Whitespace(" ")] + 1: TS_ANY_TYPE@52..55 + 0: ANY_KW@52..55 "any" [] [] + 3: (empty) + 2: R_PAREN@55..56 ")" [] [] + 5: TS_RETURN_TYPE_ANNOTATION@56..62 + 0: COLON@56..58 ":" [] [Whitespace(" ")] + 1: TS_VOID_TYPE@58..62 + 0: VOID_KW@58..62 "void" [] [] + 6: (empty) + 2: R_CURLY@62..64 "}" [Newline("\n")] [] + 3: EOF@64..65 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.ts b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.ts new file mode 100644 index 00000000000..8cb4e99879f --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_declaration.ts @@ -0,0 +1,3 @@ +declare module 'x' { + export function test(option: any): void +} diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.rast b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.rast new file mode 100644 index 00000000000..f41751fe796 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.rast @@ -0,0 +1,200 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + TsDeclareStatement { + declare_token: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")], + declaration: TsExternalModuleDeclaration { + module_token: MODULE_KW@8..15 "module" [] [Whitespace(" ")], + source: JsModuleSource { + value_token: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")], + }, + body: TsModuleBlock { + l_curly_token: L_CURLY@19..20 "{" [] [], + items: JsModuleItemList [ + JsExport { + export_token: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + export_clause: JsExportDefaultDeclarationClause { + default_token: DEFAULT_KW@30..38 "default" [] [Whitespace(" ")], + declaration: TsDeclareFunctionExportDefaultDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@38..46 "function" [] [], + id: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@46..47 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@47..53 "option" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@53..55 ":" [] [Whitespace(" ")], + ty: TsAnyType { + any_token: ANY_KW@55..58 "any" [] [], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@58..59 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@59..61 ":" [] [Whitespace(" ")], + ty: TsVoidType { + void_token: VOID_KW@61..65 "void" [] [], + }, + }, + semicolon_token: missing (optional), + }, + semicolon_token: missing (optional), + }, + }, + ], + r_curly_token: R_CURLY@65..67 "}" [Newline("\n")] [], + }, + }, + }, + TsDeclareStatement { + declare_token: DECLARE_KW@67..76 "declare" [Newline("\n")] [Whitespace(" ")], + declaration: TsExternalModuleDeclaration { + module_token: MODULE_KW@76..83 "module" [] [Whitespace(" ")], + source: JsModuleSource { + value_token: JS_STRING_LITERAL@83..87 "'y'" [] [Whitespace(" ")], + }, + body: TsModuleBlock { + l_curly_token: L_CURLY@87..88 "{" [] [], + items: JsModuleItemList [ + JsExport { + export_token: EXPORT_KW@88..98 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + export_clause: JsExportDefaultDeclarationClause { + default_token: DEFAULT_KW@98..106 "default" [] [Whitespace(" ")], + declaration: TsDeclareFunctionExportDefaultDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@106..115 "function" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@115..119 "test" [] [], + }, + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@119..120 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@120..126 "option" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@126..128 ":" [] [Whitespace(" ")], + ty: TsAnyType { + any_token: ANY_KW@128..131 "any" [] [], + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@131..132 ")" [] [], + }, + return_type_annotation: TsReturnTypeAnnotation { + colon_token: COLON@132..134 ":" [] [Whitespace(" ")], + ty: TsVoidType { + void_token: VOID_KW@134..138 "void" [] [], + }, + }, + semicolon_token: missing (optional), + }, + semicolon_token: missing (optional), + }, + }, + ], + r_curly_token: R_CURLY@138..140 "}" [Newline("\n")] [], + }, + }, + }, + ], + eof_token: EOF@140..141 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..141 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..140 + 0: TS_DECLARE_STATEMENT@0..67 + 0: DECLARE_KW@0..8 "declare" [] [Whitespace(" ")] + 1: TS_EXTERNAL_MODULE_DECLARATION@8..67 + 0: MODULE_KW@8..15 "module" [] [Whitespace(" ")] + 1: JS_MODULE_SOURCE@15..19 + 0: JS_STRING_LITERAL@15..19 "'x'" [] [Whitespace(" ")] + 2: TS_MODULE_BLOCK@19..67 + 0: L_CURLY@19..20 "{" [] [] + 1: JS_MODULE_ITEM_LIST@20..65 + 0: JS_EXPORT@20..65 + 0: EXPORT_KW@20..30 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_EXPORT_DEFAULT_DECLARATION_CLAUSE@30..65 + 0: DEFAULT_KW@30..38 "default" [] [Whitespace(" ")] + 1: TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION@38..65 + 0: (empty) + 1: FUNCTION_KW@38..46 "function" [] [] + 2: (empty) + 3: (empty) + 4: JS_PARAMETERS@46..59 + 0: L_PAREN@46..47 "(" [] [] + 1: JS_PARAMETER_LIST@47..58 + 0: JS_FORMAL_PARAMETER@47..58 + 0: JS_IDENTIFIER_BINDING@47..53 + 0: IDENT@47..53 "option" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@53..58 + 0: COLON@53..55 ":" [] [Whitespace(" ")] + 1: TS_ANY_TYPE@55..58 + 0: ANY_KW@55..58 "any" [] [] + 3: (empty) + 2: R_PAREN@58..59 ")" [] [] + 5: TS_RETURN_TYPE_ANNOTATION@59..65 + 0: COLON@59..61 ":" [] [Whitespace(" ")] + 1: TS_VOID_TYPE@61..65 + 0: VOID_KW@61..65 "void" [] [] + 6: (empty) + 2: (empty) + 2: R_CURLY@65..67 "}" [Newline("\n")] [] + 1: TS_DECLARE_STATEMENT@67..140 + 0: DECLARE_KW@67..76 "declare" [Newline("\n")] [Whitespace(" ")] + 1: TS_EXTERNAL_MODULE_DECLARATION@76..140 + 0: MODULE_KW@76..83 "module" [] [Whitespace(" ")] + 1: JS_MODULE_SOURCE@83..87 + 0: JS_STRING_LITERAL@83..87 "'y'" [] [Whitespace(" ")] + 2: TS_MODULE_BLOCK@87..140 + 0: L_CURLY@87..88 "{" [] [] + 1: JS_MODULE_ITEM_LIST@88..138 + 0: JS_EXPORT@88..138 + 0: EXPORT_KW@88..98 "export" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_EXPORT_DEFAULT_DECLARATION_CLAUSE@98..138 + 0: DEFAULT_KW@98..106 "default" [] [Whitespace(" ")] + 1: TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION@106..138 + 0: (empty) + 1: FUNCTION_KW@106..115 "function" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@115..119 + 0: IDENT@115..119 "test" [] [] + 3: (empty) + 4: JS_PARAMETERS@119..132 + 0: L_PAREN@119..120 "(" [] [] + 1: JS_PARAMETER_LIST@120..131 + 0: JS_FORMAL_PARAMETER@120..131 + 0: JS_IDENTIFIER_BINDING@120..126 + 0: IDENT@120..126 "option" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@126..131 + 0: COLON@126..128 ":" [] [Whitespace(" ")] + 1: TS_ANY_TYPE@128..131 + 0: ANY_KW@128..131 "any" [] [] + 3: (empty) + 2: R_PAREN@131..132 ")" [] [] + 5: TS_RETURN_TYPE_ANNOTATION@132..138 + 0: COLON@132..134 ":" [] [Whitespace(" ")] + 1: TS_VOID_TYPE@134..138 + 0: VOID_KW@134..138 "void" [] [] + 6: (empty) + 2: (empty) + 2: R_CURLY@138..140 "}" [Newline("\n")] [] + 3: EOF@140..141 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.ts b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.ts new file mode 100644 index 00000000000..045f4437083 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_declare_function_export_default_declaration.ts @@ -0,0 +1,6 @@ +declare module 'x' { + export default function(option: any): void +} +declare module 'y' { + export default function test(option: any): void +} 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" } diff --git a/crates/rome_js_syntax/src/generated/kind.rs b/crates/rome_js_syntax/src/generated/kind.rs index 0e6330f622b..17165ebfdeb 100644 --- a/crates/rome_js_syntax/src/generated/kind.rs +++ b/crates/rome_js_syntax/src/generated/kind.rs @@ -448,6 +448,7 @@ pub enum JsSyntaxKind { TS_EXTERNAL_MODULE_REFERENCE, TS_NAME_WITH_TYPE_ARGUMENTS, TS_DECLARE_FUNCTION_DECLARATION, + TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION, TS_DECLARE_STATEMENT, TS_INDEX_SIGNATURE_PARAMETER, TS_PROPERTY_SIGNATURE_CLASS_MEMBER, diff --git a/crates/rome_js_syntax/src/generated/macros.rs b/crates/rome_js_syntax/src/generated/macros.rs index dfb34c7c652..7e77d36b0cf 100644 --- a/crates/rome_js_syntax/src/generated/macros.rs +++ b/crates/rome_js_syntax/src/generated/macros.rs @@ -799,6 +799,12 @@ macro_rules! map_syntax_node { unsafe { $crate::TsDeclareFunctionDeclaration::new_unchecked(node) }; $body } + $crate::JsSyntaxKind::TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION => { + let $pattern = unsafe { + $crate::TsDeclareFunctionExportDefaultDeclaration::new_unchecked(node) + }; + $body + } $crate::JsSyntaxKind::TS_DECLARE_MODIFIER => { let $pattern = unsafe { $crate::TsDeclareModifier::new_unchecked(node) }; $body diff --git a/crates/rome_js_syntax/src/generated/nodes.rs b/crates/rome_js_syntax/src/generated/nodes.rs index 4ab0f93677a..f8f61442337 100644 --- a/crates/rome_js_syntax/src/generated/nodes.rs +++ b/crates/rome_js_syntax/src/generated/nodes.rs @@ -8163,6 +8163,64 @@ pub struct TsDeclareFunctionDeclarationFields { pub semicolon_token: Option, } #[derive(Clone, PartialEq, Eq, Hash)] +pub struct TsDeclareFunctionExportDefaultDeclaration { + pub(crate) syntax: SyntaxNode, +} +impl TsDeclareFunctionExportDefaultDeclaration { + #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"] + #[doc = r" or a match on [SyntaxNode::kind]"] + #[inline] + pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { Self { syntax } } + pub fn as_fields(&self) -> TsDeclareFunctionExportDefaultDeclarationFields { + TsDeclareFunctionExportDefaultDeclarationFields { + async_token: self.async_token(), + function_token: self.function_token(), + id: self.id(), + type_parameters: self.type_parameters(), + parameters: self.parameters(), + return_type_annotation: self.return_type_annotation(), + semicolon_token: self.semicolon_token(), + } + } + pub fn async_token(&self) -> Option { support::token(&self.syntax, 0usize) } + pub fn function_token(&self) -> SyntaxResult { + support::required_token(&self.syntax, 1usize) + } + pub fn id(&self) -> Option { support::node(&self.syntax, 2usize) } + pub fn type_parameters(&self) -> Option { + support::node(&self.syntax, 3usize) + } + pub fn parameters(&self) -> SyntaxResult { + support::required_node(&self.syntax, 4usize) + } + pub fn return_type_annotation(&self) -> Option { + support::node(&self.syntax, 5usize) + } + pub fn semicolon_token(&self) -> Option { support::token(&self.syntax, 6usize) } +} +#[cfg(feature = "serde")] +impl Serialize for TsDeclareFunctionExportDefaultDeclaration { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_fields().serialize(serializer) + } +} +#[cfg_attr(feature = "serde", derive(Serialize))] +pub struct TsDeclareFunctionExportDefaultDeclarationFields { + pub async_token: Option, + pub function_token: SyntaxResult, + pub id: Option, + pub type_parameters: Option, + pub parameters: SyntaxResult, + pub return_type_annotation: Option, + pub semicolon_token: Option, +} +#[derive(Clone, PartialEq, Eq, Hash)] pub struct TsDeclareModifier { pub(crate) syntax: SyntaxNode, } @@ -12621,7 +12679,7 @@ impl JsAnyExportClause { pub enum JsAnyExportDefaultDeclaration { JsClassExportDefaultDeclaration(JsClassExportDefaultDeclaration), JsFunctionExportDefaultDeclaration(JsFunctionExportDefaultDeclaration), - TsDeclareFunctionDeclaration(TsDeclareFunctionDeclaration), + TsDeclareFunctionExportDefaultDeclaration(TsDeclareFunctionExportDefaultDeclaration), TsInterfaceDeclaration(TsInterfaceDeclaration), } impl JsAnyExportDefaultDeclaration { @@ -12641,9 +12699,13 @@ impl JsAnyExportDefaultDeclaration { _ => None, } } - pub fn as_ts_declare_function_declaration(&self) -> Option<&TsDeclareFunctionDeclaration> { + pub fn as_ts_declare_function_export_default_declaration( + &self, + ) -> Option<&TsDeclareFunctionExportDefaultDeclaration> { match &self { - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(item) => Some(item), + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(item) => { + Some(item) + } _ => None, } } @@ -21364,6 +21426,56 @@ impl From for SyntaxNode { impl From for SyntaxElement { fn from(n: TsDeclareFunctionDeclaration) -> SyntaxElement { n.syntax.into() } } +impl AstNode for TsDeclareFunctionExportDefaultDeclaration { + type Language = Language; + const KIND_SET: SyntaxKindSet = SyntaxKindSet::from_raw(RawSyntaxKind( + TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION as u16, + )); + fn can_cast(kind: SyntaxKind) -> bool { kind == TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn into_syntax(self) -> SyntaxNode { self.syntax } +} +impl std::fmt::Debug for TsDeclareFunctionExportDefaultDeclaration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TsDeclareFunctionExportDefaultDeclaration") + .field( + "async_token", + &support::DebugOptionalElement(self.async_token()), + ) + .field( + "function_token", + &support::DebugSyntaxResult(self.function_token()), + ) + .field("id", &support::DebugOptionalElement(self.id())) + .field( + "type_parameters", + &support::DebugOptionalElement(self.type_parameters()), + ) + .field("parameters", &support::DebugSyntaxResult(self.parameters())) + .field( + "return_type_annotation", + &support::DebugOptionalElement(self.return_type_annotation()), + ) + .field( + "semicolon_token", + &support::DebugOptionalElement(self.semicolon_token()), + ) + .finish() + } +} +impl From for SyntaxNode { + fn from(n: TsDeclareFunctionExportDefaultDeclaration) -> SyntaxNode { n.syntax } +} +impl From for SyntaxElement { + fn from(n: TsDeclareFunctionExportDefaultDeclaration) -> SyntaxElement { n.syntax.into() } +} impl AstNode for TsDeclareModifier { type Language = Language; const KIND_SET: SyntaxKindSet = @@ -26347,9 +26459,9 @@ impl From for JsAnyExportDefaultDeclaration JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(node) } } -impl From for JsAnyExportDefaultDeclaration { - fn from(node: TsDeclareFunctionDeclaration) -> JsAnyExportDefaultDeclaration { - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(node) +impl From for JsAnyExportDefaultDeclaration { + fn from(node: TsDeclareFunctionExportDefaultDeclaration) -> JsAnyExportDefaultDeclaration { + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(node) } } impl From for JsAnyExportDefaultDeclaration { @@ -26361,14 +26473,14 @@ impl AstNode for JsAnyExportDefaultDeclaration { type Language = Language; const KIND_SET: SyntaxKindSet = JsClassExportDefaultDeclaration::KIND_SET .union(JsFunctionExportDefaultDeclaration::KIND_SET) - .union(TsDeclareFunctionDeclaration::KIND_SET) + .union(TsDeclareFunctionExportDefaultDeclaration::KIND_SET) .union(TsInterfaceDeclaration::KIND_SET); fn can_cast(kind: SyntaxKind) -> bool { matches!( kind, JS_CLASS_EXPORT_DEFAULT_DECLARATION | JS_FUNCTION_EXPORT_DEFAULT_DECLARATION - | TS_DECLARE_FUNCTION_DECLARATION + | TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION | TS_INTERFACE_DECLARATION ) } @@ -26384,9 +26496,9 @@ impl AstNode for JsAnyExportDefaultDeclaration { JsFunctionExportDefaultDeclaration { syntax }, ) } - TS_DECLARE_FUNCTION_DECLARATION => { - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration( - TsDeclareFunctionDeclaration { syntax }, + TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION => { + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration( + TsDeclareFunctionExportDefaultDeclaration { syntax }, ) } TS_INTERFACE_DECLARATION => { @@ -26402,7 +26514,9 @@ impl AstNode for JsAnyExportDefaultDeclaration { match self { JsAnyExportDefaultDeclaration::JsClassExportDefaultDeclaration(it) => &it.syntax, JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(it) => &it.syntax, - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(it) => &it.syntax, + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(it) => { + &it.syntax + } JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(it) => &it.syntax, } } @@ -26410,7 +26524,9 @@ impl AstNode for JsAnyExportDefaultDeclaration { match self { JsAnyExportDefaultDeclaration::JsClassExportDefaultDeclaration(it) => it.syntax, JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(it) => it.syntax, - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(it) => it.syntax, + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(it) => { + it.syntax + } JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(it) => it.syntax, } } @@ -26424,7 +26540,7 @@ impl std::fmt::Debug for JsAnyExportDefaultDeclaration { JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(it) => { std::fmt::Debug::fmt(it, f) } - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(it) => { + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(it) => { std::fmt::Debug::fmt(it, f) } JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(it) => { @@ -26438,7 +26554,9 @@ impl From for SyntaxNode { match n { JsAnyExportDefaultDeclaration::JsClassExportDefaultDeclaration(it) => it.into(), JsAnyExportDefaultDeclaration::JsFunctionExportDefaultDeclaration(it) => it.into(), - JsAnyExportDefaultDeclaration::TsDeclareFunctionDeclaration(it) => it.into(), + JsAnyExportDefaultDeclaration::TsDeclareFunctionExportDefaultDeclaration(it) => { + it.into() + } JsAnyExportDefaultDeclaration::TsInterfaceDeclaration(it) => it.into(), } } @@ -32830,6 +32948,11 @@ impl std::fmt::Display for TsDeclareFunctionDeclaration { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for TsDeclareFunctionExportDefaultDeclaration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for TsDeclareModifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/rome_js_syntax/src/generated/nodes_mut.rs b/crates/rome_js_syntax/src/generated/nodes_mut.rs index ea730d2c4ee..4c21d21fa8d 100644 --- a/crates/rome_js_syntax/src/generated/nodes_mut.rs +++ b/crates/rome_js_syntax/src/generated/nodes_mut.rs @@ -4028,6 +4028,50 @@ impl TsDeclareFunctionDeclaration { ) } } +impl TsDeclareFunctionExportDefaultDeclaration { + pub fn with_async_token(self, element: Option) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), + ) + } + pub fn with_function_token(self, element: SyntaxToken) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(1usize..=1usize, once(Some(element.into()))), + ) + } + pub fn with_id(self, element: Option) -> Self { + Self::unwrap_cast(self.syntax.splice_slots( + 2usize..=2usize, + once(element.map(|element| element.into_syntax().into())), + )) + } + pub fn with_type_parameters(self, element: Option) -> Self { + Self::unwrap_cast(self.syntax.splice_slots( + 3usize..=3usize, + once(element.map(|element| element.into_syntax().into())), + )) + } + pub fn with_parameters(self, element: JsParameters) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(4usize..=4usize, once(Some(element.into_syntax().into()))), + ) + } + pub fn with_return_type_annotation(self, element: Option) -> Self { + Self::unwrap_cast(self.syntax.splice_slots( + 5usize..=5usize, + once(element.map(|element| element.into_syntax().into())), + )) + } + pub fn with_semicolon_token(self, element: Option) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(6usize..=6usize, once(element.map(|element| element.into()))), + ) + } +} impl TsDeclareModifier { pub fn with_modifier_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 2f33983b60e..76dc9778175 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -1371,8 +1371,8 @@ JsExportDefaultDeclarationClause = JsAnyExportDefaultDeclaration = JsClassExportDefaultDeclaration | JsFunctionExportDefaultDeclaration - | TsDeclareFunctionDeclaration | TsInterfaceDeclaration + | TsDeclareFunctionExportDefaultDeclaration // export default class {} @@ -1733,6 +1733,20 @@ TsDeclareFunctionDeclaration = return_type_annotation: TsReturnTypeAnnotation? ';'? +// declaration of a export default function without a body +// declare module 'x' { +// export default function(option: any): void +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// } +TsDeclareFunctionExportDefaultDeclaration = + 'async'? + 'function' + id: JsAnyBinding? + type_parameters: TsTypeParameters? + parameters: JsParameters + return_type_annotation: TsReturnTypeAnnotation? + ';'? + TsModuleDeclaration = module_or_namespace: ('module' | 'namespace') diff --git a/xtask/codegen/src/kinds_src.rs b/xtask/codegen/src/kinds_src.rs index 1ba78990be7..3e674f4f664 100644 --- a/xtask/codegen/src/kinds_src.rs +++ b/xtask/codegen/src/kinds_src.rs @@ -468,6 +468,7 @@ pub const JS_KINDS_SRC: KindsSrc = KindsSrc { "TS_EXTERNAL_MODULE_REFERENCE", "TS_NAME_WITH_TYPE_ARGUMENTS", "TS_DECLARE_FUNCTION_DECLARATION", + "TS_DECLARE_FUNCTION_EXPORT_DEFAULT_DECLARATION", "TS_DECLARE_STATEMENT", "TS_INDEX_SIGNATURE_PARAMETER", "TS_PROPERTY_SIGNATURE_CLASS_MEMBER",