diff --git a/crates/flavor-plugin-typescript/src/parser/declarations.rs b/crates/flavor-plugin-typescript/src/parser/declarations.rs index 5bc6935..e2ed669 100644 --- a/crates/flavor-plugin-typescript/src/parser/declarations.rs +++ b/crates/flavor-plugin-typescript/src/parser/declarations.rs @@ -112,7 +112,7 @@ impl<'a> Parser<'a> { } self.parse_modifier_list(); self.bump(); - if self.at(kind::IDENTIFIER) { + if is_function_name(self.current()) { self.bump(); } else { self.error_here("expected function name"); @@ -262,3 +262,10 @@ impl<'a> Parser<'a> { self.builder.finish_node(); } } + +fn is_function_name(kind: kind::Kind) -> bool { + matches!( + kind, + kind::IDENTIFIER | kind::KEYWORD_GET | kind::KEYWORD_SET + ) +} diff --git a/crates/flavor-plugin-typescript/tests/parser.rs b/crates/flavor-plugin-typescript/tests/parser.rs index e59f30e..1d9870b 100644 --- a/crates/flavor-plugin-typescript/tests/parser.rs +++ b/crates/flavor-plugin-typescript/tests/parser.rs @@ -140,6 +140,19 @@ mod declarations { assert!(output.diagnostics.is_empty()); } + #[test] + fn contextual_function_name() { + let output = ts_output( + r#"function get(name: string, fallback = ""): string { return Deno.env.get(name) ?? fallback; } export const env = { get };"#, + ); + + assert!(has_node(&output, kind::FUNCTION_DECLARATION)); + assert!(has_node(&output, kind::PARAMETER_LIST)); + assert!(has_node(&output, kind::RETURN_TYPE)); + assert!(has_node(&output, kind::EXPORT_DECLARATION)); + assert!(output.diagnostics.is_empty(), "{:?}", output.diagnostics); + } + #[test] fn function_return_object_type() { let output = ts_output(