Пример #1
0
    def visit_Compare(self, node):
        if self._language in {"dart", "kotlin", "nim", "python"}:
            return node

        if isinstance(node.ops[0], ast.In):
            left = node.left
            right = node.comparators[0]
            left_type = get_id(get_inferred_type(left))
            right_type = get_id(get_inferred_type(right))
            if left_type == "str" and right_type == "str":
                if self._language == "julia":
                    ret = ast.parse("findfirst(a, b) != Nothing").body[0].value
                    ret.left.args[0] = left
                    ret.left.args[1] = right
                elif self._language == "go":
                    # To be rewritten to strings.Contains via plugins
                    ret = ast.parse("StringsContains(a, b)").body[0].value
                    ret.args[0] = right
                    ret.args[1] = left
                elif self._language == "cpp":
                    ret = ast.parse("a.find(b) != string.npos").body[0].value
                    ret.left.func.value = right
                    ret.left.args[0] = left
                else:
                    # rust and c++23
                    ret = ast.parse("a.contains(b)").body[0].value
                    ret.func.value = right
                    ret.args[0] = left
                ret.lineno = node.lineno
                ast.fix_missing_locations(ret)
                return ret

        return node
Пример #2
0
 def visit_BinOp(self, node):
     self.generic_visit(node)
     if isinstance(node.op, ast.Div):
         left_type = get_id(get_inferred_type(node.left))
         right_type = get_id(get_inferred_type(node.right))
         if set([left_type, right_type]) == {"int"}:
             # This attribute should technically be on node.op
             # But python seems to use the same AST node for other
             # division operations?
             node.use_integer_div = True
     return node
Пример #3
0
def get_inferred_rust_type(node):
    if hasattr(node, "rust_annotation"):
        return node.rust_annotation
    if isinstance(node, ast.Name):
        if not hasattr(node, "scopes"):
            return None
        definition = node.scopes.find(get_id(node))
        # Prevent infinite recursion
        if definition != node:
            return get_inferred_rust_type(definition)
    python_type = get_inferred_type(node)
    ret = map_type(get_id(python_type))
    node.rust_annotation = ret
    return ret
Пример #4
0
def get_inferred_kotlin_type(node):
    if isinstance(node, ast.Call):
        fname = get_id(node.func)
        if fname in {"max", "min", "floor"}:
            return "float64"
    if isinstance(node, ast.Name):
        if not hasattr(node, "scopes"):
            return None
        definition = node.scopes.find(get_id(node))
        # Prevent infinite recursion
        if definition != node:
            return get_inferred_kotlin_type(definition)
    if hasattr(node, "kotlin_annotation"):
        return node.kotlin_annotation
    python_type = get_inferred_type(node)
    return map_type(get_id(python_type))
Пример #5
0
    def visit_Assign(self, node):
        target = node.targets[0]  # Assumes all targets have same annotation
        if isinstance(target, ast.Subscript):
            return node
        annotation = getattr(target, "annotation", False)
        if not annotation:
            return node

        if isinstance(annotation, ast.ClassDef):
            annotation = ast.Name(id=get_id(annotation))

        col_offset = getattr(node, "col_offset", None)

        assigns = []
        for assign_target in node.targets:
            definition = node.scopes.parent_scopes.find(get_id(assign_target))
            if definition is None:
                definition = node.scopes.find(get_id(assign_target))
            if definition is not assign_target:
                previous_type = get_inferred_type(definition)
                if get_id(previous_type) == get_id(annotation):
                    if len(node.targets) == 1:
                        return node
                    else:
                        new_node = ast.Assign(
                            targets=[assign_target],
                            value=node.value,
                            lineno=node.lineno,
                            col_offset=col_offset,
                        )
                        assigns.append(new_node)
                        continue
            new_node = ast.AnnAssign(
                target=assign_target,
                value=node.value,
                lineno=node.lineno,
                col_offset=col_offset,
                simple=True,
                annotation=annotation,
            )
            assigns.append(new_node)

        if len(assigns) == 1:
            return assigns[0]

        return create_ast_block(body=assigns, at_node=node)