def visit_FunctionDef(self, node): body = "\n".join([self.visit(n) for n in node.body]) # If rewriter inserted a block, we need to terminate it with a semicolon if len(node.body): last = node.body[-1] if getattr(last, "make_block", False): body += ";" if (self.use_catch_test_cases and is_void_function(node) and node.name.startswith("test")): return generate_catch_test_case(node, body) is_python_main = getattr(node, "python_main", False) typenames, args = self.visit(node.args) args_list = [] if len(args) and hasattr(node, "self_type"): # implicit this del typenames[0] del args[0] typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 if is_python_main and arg in ["argv"]: typename = "char **" args_list.append(f"{typename} {arg}") template = "inline " if len(typedecls) > 0: typedecls_str = ", ".join([f"typename {t}" for t in typedecls]) template = f"template <{typedecls_str}>" if is_python_main: body = ( "pycpp::sys::argv = std::vector<std::string>(argv, argv + argc);\n" + body) template = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f"{typename}" else: return_type = "auto" else: return_type = "void" args = ", ".join(args_list) funcdef = f"{template}{return_type} {node.name}({args}) {{" return funcdef + "\n" + body + "}\n"
def visit_FunctionDef(self, node): body = "\n".join([self.visit(n) for n in node.body]) if (self.use_catch_test_cases and is_void_function(node) and node.name.startswith("test")): return generate_catch_test_case(node, body) typenames, args = self.visit(node.args) args_list = [] if len(args) and hasattr(node, "self_type"): # implicit this del typenames[0] del args[0] typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 args_list.append(f"{typename} {arg}") template = "inline " if len(typedecls) > 0: typedecls_str = ", ".join([f"typename {t}" for t in typedecls]) template = f"template <{typedecls_str}>" return_type = "auto" if node.name == "main": template = "" return_type = "int" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f"{typename}" else: return_type = "auto" else: return_type = "void" args = ", ".join(args_list) funcdef = f"{template}{return_type} {node.name}({args}) {{" if getattr(node, "python_main", False): funcdef = "\n".join([ "int main(int argc, char ** argv) {", "py14::sys::argv = " "std::vector<std::string>(argv, argv + argc);", ]) return funcdef + "\n" + body + "}\n"
def visit_FunctionDef(self, node): body = "\n".join([self.visit(n) for n in node.body]) typenames, args = self.visit(node.args) if len(typenames) and typenames[0] == None and hasattr(node, "self_type"): typenames[0] = node.self_type args_list = [] typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0} any".format(index) typedecls.append(typename) index += 1 args_list.append(f"{arg} {typename}") return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f" {typename}" else: return_type = " RT" typedecls.append("RT") template = "" if len(typedecls) > 0: template = "[{0}]".format(", ".join(typedecls)) args = ", ".join(args_list) funcdef = f"func {node.name}{template}({args}){return_type} {{" return f"{funcdef}\n{body}}}\n\n"
def visit_FunctionDef(self, node) -> str: body = "\n".join([self.indent(self.visit(n)) for n in node.body]) typenames, args = self.visit(node.args) is_python_main = getattr(node, "python_main", False) args_list = [] if len(args) and hasattr(node, "self_type"): typenames[0] = node.self_type for i in range(len(args)): typename = typenames[i] arg = args[i] args_list.append(f"{arg}: {typename}".format(arg, typename)) return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f": {typename}" else: return_type = "" args = ", ".join(args_list) funcdef = f"proc {node.name}({args}){return_type} =" maybe_main = "" if is_python_main: maybe_main = "\nmain()" return f"{funcdef}\n{body}\n{maybe_main}"
def visit_FunctionDef(self, node): body = "\n".join([self.indent(self.visit(n)) for n in node.body]) typenames, args = self.visit(node.args) args_list = [] if len(args) and hasattr(node, "self_type"): typenames[0] = node.self_type for i in range(len(args)): typename = typenames[i] arg = args[i] args_list.append(f"(declare-const {arg} {typename})") return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f" {typename}" else: return_type = "" if len(node.body) == 1 and is_ellipsis(node.body[0]): return self._visit_DeclareFunc(node, return_type) args = "\n".join(args_list) funcdef = f"define-fun {node.name}() {return_type}" return f"{args}\n({funcdef}\n{body})\n"
def visit_FunctionDef(self, node, async_prefix=""): body = "\n".join([self.visit(n) for n in node.body]) typenames, args = self.visit(node.args) args_list = [] if args and args[0] == "self": del typenames[0] del args[0] args_list.append("&self") is_python_main = getattr(node, "python_main", False) if is_python_main: self._usings.add("anyhow::Result") typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 args_list.append("{0}: {1}".format(arg, typename)) return_type = "" if not is_python_main else "-> Result<()>" if node.returns: typename = self._typename_from_annotation(node, attr="returns") if getattr(node.returns, "rust_needs_reference", False): typename = f"&{typename}" if getattr(node, "rust_pyresult_type", False): if node.no_return: typename = None else: typename = self._generic_typename_from_type_node( node.returns) typename = map_type(typename, extension=True, return_type=True) if typename != "_": return_type = f"-> {typename}" else: if not is_void_function(node): return_type = "-> RT" typedecls.append("RT") template = "" if len(typedecls) > 0: template = "<{0}>".format(", ".join(typedecls)) extension = "#[pyfunction]\n" if self.extension else "" args_list = ", ".join(args_list) funcdef = f"{extension}pub {async_prefix}fn {node.name}{template}({args_list}) {return_type}" return_success = ( "Ok(())" if is_python_main else "" ) # TODO: generalize this to functions that return Result<T, E> return f"{funcdef} {{\n{body}\n {return_success}}}\n"
def visit_FunctionDef(self, node): body = "\n".join([self.visit(n) for n in node.body]) typenames, args = self.visit(node.args) args_list = [] if len(args) and hasattr(node, "self_type"): # implicit this del typenames[0] del args[0] is_python_main = getattr(node, "python_main", False) typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if is_python_main and arg == "argc": continue if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 args_list.append(f"{typename} {arg}") return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") if typename != self._default_type: return_type = f"{typename}" if not return_type: return_type = "RT" typedecls.append("RT") template = "" if len(typedecls) > 0: template = "<{0}>".format(", ".join(typedecls)) args = ", ".join(args_list) funcdef = f"{return_type} {node.name}{template}({args}) {{" return funcdef + "\n" + body + "}\n\n"
def visit_FunctionDef(self, node): body = "\n".join([self.visit(n) for n in node.body]) typenames, args = self.visit(node.args) args_list = [] typedecls = [] index = 0 is_python_main = getattr(node, "python_main", False) if len(typenames) and typenames[0] == None and hasattr( node, "self_type"): typenames[0] = node.self_type for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 args_list.append("{0}::{1}".format(arg, typename)) return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") return_type = f"::{typename}" else: return_type = "::RT" typedecls.append("RT") template = "" if len(typedecls) > 0: template = "{{{0}}}".format(", ".join(typedecls)) args = ", ".join(args_list) funcdef = f"function {node.name}{template}({args}){return_type}" maybe_main = "" if is_python_main: maybe_main = "\nmain()" return f"{funcdef}\n{body}\nend\n{maybe_main}"
def visit_FunctionDef(self, node, async_prefix=""): body = "\n".join([self.visit(n) for n in node.body]) typenames, args = self.visit(node.args) args_list = [] if args and args[0] == "self": del typenames[0] del args[0] args_list.append("&self") typedecls = [] index = 0 for i in range(len(args)): typename = typenames[i] arg = args[i] if typename == "T": typename = "T{0}".format(index) typedecls.append(typename) index += 1 args_list.append("{0}: {1}".format(arg, typename)) return_type = "" if not is_void_function(node): if node.returns: typename = self._typename_from_annotation(node, attr="returns") if getattr(node.returns, "rust_needs_reference", False): typename = f"&{typename}" return_type = f"-> {typename}" else: return_type = "-> RT" typedecls.append("RT") template = "" if len(typedecls) > 0: template = "<{0}>".format(", ".join(typedecls)) extension = "#[pyfunction]\n" if self.extension else "" args_list = ", ".join(args_list) funcdef = f"{extension}pub {async_prefix}fn {node.name}{template}({args_list}) {return_type}" return funcdef + " {\n" + body + "\n}\n"
def visit_FunctionDef(self, node) -> str: signature = ["fn"] if node.scopes[-1] is ast.ClassDef: raise AstNotImplementedError( "Class methods are not supported yet.", node) signature.append(node.name) generics: Set[str] = set() args: List[Tuple[str, str]] = [] for arg in node.args.args: typename, id = self.visit(arg) if typename is None: # receiver typename = "<struct name>" # TODO: fetch struct name from node.scopes elif len(typename) == 1 and typename.isupper(): generics.add(typename) args.append((typename, id)) str_args: List[str] = [] for typename, id in args: if typename == "": for c in string.ascii_uppercase: if c not in generics: generics.add(c) typename = c if typename == "": raise AstNotImplementedError( "Cannot use more than 26 generics in a function.", node) str_args.append(f"{id} {typename}") signature.append(f"({', '.join(str_args)})") if not is_void_function(node): signature.append( self._typename_from_annotation(node, attr="returns")) body = "\n".join([self.indent(self.visit(n)) for n in node.body]) return f"{' '.join(signature)} {{\n{body}\n}}"
def test_is_not_void_for_fun_with_return_value(): source = parse("def foo(x):", " return x") foo = source.body[0] assert not is_void_function(foo)
def test_is_void_for_fun_with_no_return(): source = parse("def foo(x):", " bar(x)") foo = source.body[0] assert is_void_function(foo)