Exemplo n.º 1
0
    def visit_Call(self, node):
        fname = self.visit(node.func)
        fndef = node.scopes.find(fname)

        if isinstance(fndef, ast.ClassDef):
            return self._visit_struct_literal(node, fname, fndef)

        vargs = []  # visited args
        if node.args:
            vargs += [self.visit(a) for a in node.args]
        if node.keywords:
            vargs += [self.visit(kw.value) for kw in node.keywords]

        ret = self._dispatch(node, fname, vargs)
        if ret is not None:
            return ret

        # Check if some args need to be passed by reference
        ref_args = []
        if fndef and hasattr(fndef, "args"):
            for varg, fnarg, node_arg in zip(vargs, fndef.args.args,
                                             node.args):
                if is_reference(fnarg) and not is_reference(node_arg):
                    ref_args.append(f"&{varg}")
                else:
                    ref_args.append(varg)
        else:
            ref_args = vargs

        args = ", ".join(ref_args)
        return f"{fname}({args})"
Exemplo n.º 2
0
 def visit_Return(self, node):
     fndef = None
     for scope in node.scopes:
         if isinstance(scope, ast.FunctionDef):
             fndef = scope
             break
     if node.value:
         ret = self.visit(node.value)
         if fndef:
             if getattr(fndef, "rust_pyresult_type", False):
                 # TODO: Design a more robust solution for this
                 # For now, PyResult and references don't mix
                 if ret.startswith("&"):
                     ret = ret[1:]
                 ret = f"Ok({ret})"
             return_type = self._typename_from_annotation(fndef,
                                                          attr="returns")
             value_type = get_inferred_rust_type(node.value)
             if is_reference(node.value) and not getattr(
                     fndef.returns, "rust_needs_reference", True):
                 # TODO: Handle other container types
                 ret = f"{ret}.to_vec()"
             if return_type != value_type and value_type is not None:
                 return f"return {ret} as {return_type};"
         return f"return {ret};"
     if fndef:
         if getattr(fndef, "rust_pyresult_type", False):
             return "return Ok(())"
     return "return;"
Exemplo n.º 3
0
def is_rust_reference(node):
    if not is_reference(node):
        return False
    if isinstance(node, ast.Call):
        definition = node.scopes.find(get_id(node.func))
        needs_reference = getattr(definition, "rust_return_needs_reference",
                                  True)
        return needs_reference
    return True
Exemplo n.º 4
0
    def visit_Call(self, node):
        fname = self.visit(node.func)
        fndef = node.scopes.find(fname)

        if isinstance(fndef, ast.ClassDef):
            return self._visit_struct_literal(node, fname, fndef)

        vargs = []  # visited args
        if node.args:
            vargs += [self.visit(a) for a in node.args]
        if node.keywords:
            vargs += [self.visit(kw.value) for kw in node.keywords]

        ret = self._dispatch(node, fname, vargs)
        node_result_type = getattr(node, "result_type", False)
        node_func_result_type = getattr(node.func, "result_type", False)
        if ret is not None:
            if ret.startswith("std::process::exit("):
                node_result_type = False
            unwrap = "?" if node_result_type or node_func_result_type else ""
            return f"{ret}{unwrap}"

        # Check if some args need to be passed by reference
        ref_args = []
        if fndef and hasattr(fndef, "args"):
            for varg, fnarg, node_arg in zip(vargs, fndef.args.args,
                                             node.args):
                if is_reference(fnarg) and not is_reference(node_arg):
                    ref_args.append(f"&{varg}")
                else:
                    ref_args.append(varg)
        else:
            ref_args = vargs

        args = ", ".join(ref_args)
        unwrap = "?" if node_result_type or node_func_result_type else ""
        return f"{fname}({args}){unwrap}"
Exemplo n.º 5
0
 def visit_Return(self, node):
     self.generic_visit(node)
     if node.value:
         fndef = None
         for scope in node.scopes:
             if isinstance(scope, ast.FunctionDef):
                 fndef = scope
                 break
         if fndef:
             if is_reference(node.value):
                 mut = is_mutable(node.scopes, get_id(node.value))
                 fndef.returns.rust_needs_reference = not mut
                 fndef.rust_return_needs_reference = (
                     fndef.returns.rust_needs_reference)
     return node
Exemplo n.º 6
0
 def visit_Return(self, node):
     if node.value:
         ret = self.visit(node.value)
         fndef = None
         for scope in node.scopes:
             if isinstance(scope, ast.FunctionDef):
                 fndef = scope
                 break
         if fndef:
             return_type = self._typename_from_annotation(fndef,
                                                          attr="returns")
             value_type = get_inferred_rust_type(node.value)
             if is_reference(node.value) and not getattr(
                     fndef.returns, "rust_needs_reference", True):
                 # TODO: Handle other container types
                 ret = f"{ret}.to_vec()"
             if return_type != value_type and value_type is not None:
                 return f"return {ret} as {return_type};"
         return f"return {ret};"
     return "return;"
Exemplo n.º 7
0
 def visit_For(self, node):
     if hasattr(node.iter, "id"):
         definition = node.scopes.find(node.iter.id)
         if is_reference(definition):
             node.target.needs_dereference = True
     return node