diff --git a/src/codegen/sdk/core/detached_symbols/function_call.py b/src/codegen/sdk/core/detached_symbols/function_call.py index 4507e65ff..2c2d32af3 100644 --- a/src/codegen/sdk/core/detached_symbols/function_call.py +++ b/src/codegen/sdk/core/detached_symbols/function_call.py @@ -221,6 +221,33 @@ def asyncify(self) -> None: self.insert_before("await (", newline=False) self.insert_after(")", newline=False) + @writer + def deAsyncify(self) -> None: + """Removes the 'await' keyword from an awaited function call. + + This method removes the 'await' syntax from a function call if it is awaited, converting it back to a regular function call. + + Args: + None + + Returns: + None + """ + if not self.is_awaited: + return + + # Find the await keyword and remove it along with any surrounding parentheses + parent = self.ts_node.parent + if parent and parent.type == "await_expression": + # Check if the await expression is wrapped in parentheses + if parent.parent and parent.parent.type == "parenthesized_expression": + # Remove the await keyword and both parentheses + self.remove_byte_range(parent.parent.start_byte, self.ts_node.start_byte) + self.remove_byte_range(self.ts_node.end_byte, parent.parent.end_byte) + else: + # Remove just the await keyword + self.remove_byte_range(parent.start_byte, self.ts_node.start_byte) + @property @reader def predecessor(self) -> FunctionCall[Parent] | None: diff --git a/src/codegen/sdk/typescript/expressions/function_type.py b/src/codegen/sdk/typescript/expressions/function_type.py index 85807bade..61d038ef1 100644 --- a/src/codegen/sdk/typescript/expressions/function_type.py +++ b/src/codegen/sdk/typescript/expressions/function_type.py @@ -75,6 +75,35 @@ def asyncify(self) -> None: self.return_type.insert_before("Promise<", newline=False) self.return_type.insert_after(">", newline=False) + @writer + def deAsyncify(self) -> None: + """Modifies the function type to be synchronous by unwrapping its return type from a Promise. + + This method transforms an asynchronous function type into a synchronous one by modifying + its return type. It unwraps the existing return type from a Promise, effectively changing + 'Promise' to 'T'. + + Args: + self: The TSFunctionType instance to modify. + + Returns: + None + """ + if self.return_type and self.return_type.name == "Promise": + # Check if it's a generic Promise + if "<" in self.return_type.source and ">" in self.return_type.source: + # Extract the type inside Promise + inner_type = self.return_type.source[self.return_type.source.find("<") + 1 : self.return_type.source.rfind(">")] + if inner_type.strip(): + # Replace Promise with T + self.return_type.edit(inner_type) + else: + # If Promise<> is empty or just whitespace, remove the return type + self.return_type.edit("") + else: + # If it's just Promise without generic type, remove it + self.return_type.edit("") + def _compute_dependencies(self, usage_type: UsageKind | None = None, dest: Importable | None = None): if self.return_type: self.return_type._compute_dependencies(UsageKind.GENERIC, dest) diff --git a/src/codegen/sdk/typescript/function.py b/src/codegen/sdk/typescript/function.py index ee71ee9db..1c4192e53 100644 --- a/src/codegen/sdk/typescript/function.py +++ b/src/codegen/sdk/typescript/function.py @@ -304,6 +304,44 @@ def asyncify(self) -> None: self.return_type.insert_before("Promise<", newline=False) self.return_type.insert_after(">", newline=False) + @writer + def deAsyncify(self) -> None: + """Modifies the function to be synchronous, if it is asynchronous. + + This method converts an asynchronous function to be synchronous by removing the 'async' keyword and unwrapping + the return type from a Promise if a return type exists. + + Returns: + None + + Note: + If the function is already synchronous, this method does nothing. + """ + if not self.is_async: + return + + # Remove the 'async' keyword + for child in self.ts_node.children: + if child.type == "async": + self.remove_byte_range(child.start_byte, child.end_byte) + break + + # Unwrap the return type from Promise if it exists + if self.return_type and self.return_type.name == "Promise": + # Check if it's a generic Promise + if "<" in self.return_type.source and ">" in self.return_type.source: + # Extract the type inside Promise + inner_type = self.return_type.source[self.return_type.source.find("<") + 1 : self.return_type.source.rfind(">")] + if inner_type.strip(): + # Replace Promise with T + self.return_type.edit(inner_type) + else: + # If Promise<> is empty or just whitespace, remove the return type + self.return_type.edit("") + else: + # If it's just Promise without generic type, remove it + self.return_type.edit("") + @writer def arrow_to_named(self, name: str | None = None) -> None: """Converts an arrow function to a named function in TypeScript/JavaScript.