def visit_Name(self, node): if hasattr(node, "scopes") and is_global(node): old_name = get_id(node) new_name = camel_case(old_name) if old_name != new_name: rename(node.scopes[-1], old_name, new_name) return node
def _compute_kw(self, node, target) -> str: kw = "let" mut = is_mutable(node.scopes, get_id(target)) if is_global(node) or getattr(node, "class_assignment", False): # Note that static are not really supported, as modifying them requires adding # "unsafe" blocks, which pyrs does not do. kw = "pub static" if mut else "pub const" elif mut: kw = "let mut" return kw
def _visit_AssignOne(self, node, target): if isinstance(target, ast.Tuple): elts = [self.visit(e) for e in target.elts] value = self.visit(node.value) return "var {0} = {1}".format(", ".join(elts), value) if isinstance(node.scopes[-1], ast.If): outer_if = node.scopes[-1] target_id = self.visit(target) if target_id in outer_if.common_vars: value = self.visit(node.value) return "{0} = {1}".format(target_id, value) if isinstance(target, ast.Subscript) or isinstance( target, ast.Attribute): target = self.visit(target) value = self.visit(node.value) if value == None: value = "None" return "{0} = {1}".format(target, value) typename = self._typename_from_annotation(target) needs_cast = self._needs_cast(target, node.value) target_str = self.visit(target) value = self.visit(node.value) if needs_cast: left_annotation = target.annotation right_annotation = getattr(node.value, "annotation", None) if right_annotation is None: right_annotation = ast.Name( id=get_inferred_go_type(node.value)) value = self._assign_cast(value, typename, left_annotation, right_annotation) definition = node.scopes.parent_scopes.find(get_id(target)) if definition is None: definition = node.scopes.find(get_id(target)) if isinstance(target, ast.Name) and defined_before(definition, node): return f"{target_str} = {value}" else: if typename is not None: # Dummy assign to silence the compiler on unused vars maybe_tail = "" if target_str.startswith("_") and target_str != "_": maybe_tail = f"\n_ = {target_str}" if target_str == "_": return f"{target_str} = {value}" return f"var {target_str} {typename} = {value}{maybe_tail}" if is_global(node): return f"var {target_str} = {value}" return f"{target_str} := {value}"
def _visit_AssignOne(self, node, target): if isinstance(target, ast.Tuple): elts = [self.visit(e) for e in target.elts] value = self.visit(node.value) return "std::tie({0}) = {1};".format(", ".join(elts), value) if isinstance(node.scopes[-1], ast.If) and isinstance( target, ast.Name): outer_if = node.scopes[-1] if target.id in outer_if.common_vars: value = self.visit(node.value) return "{0} = {1};".format(target.id, value) if isinstance(target, ast.Subscript): target = self.visit(target) value = self.visit(node.value) return "{0} = {1};".format(target, value) definition = node.scopes.parent_scopes.find(get_id(target)) if definition is None: definition = node.scopes.find(get_id(target)) if isinstance(target, ast.Name) and defined_before(definition, node): target = self.visit(target) value = self.visit(node.value) return "{0} = {1};".format(target, value) if isinstance(node.value, ast.List): element_type = self._get_element_type(node.value) if element_type == self._default_type: typename = decltype(node) else: typename = f"std::vector<{element_type}>" else: typename = self._typename_from_annotation(target) target = self.visit(target) value = self.visit(node.value) lint_exception = " // NOLINT(runtime/string)" if not self._no_prologue else "" if typename == "std::string" and is_global(node): return f"{typename} {target} = {value};{lint_exception}" return f"{typename} {target} = {value};"
def _visit_AssignOne(self, node, target): kw = "let" mut = is_mutable(node.scopes, get_id(target)) if is_global(node): # Note that static are not really supported, as modifying them requires adding # "unsafe" blocks, which pyrs does not do. kw = "pub static" if mut else "pub const" elif mut: kw = "let mut" if isinstance(target, ast.Tuple): elts = ", ".join([self.visit(e) for e in target.elts]) value = self.visit(node.value) return f"{kw} ({elts}) = {value};" if isinstance(node.scopes[-1], ast.If): outer_if = node.scopes[-1] target_id = self.visit(target) if target_id in outer_if.common_vars: value = self.visit(node.value) return "{0} = {1};".format(target_id, value) if isinstance(target, ast.Subscript) or isinstance( target, ast.Attribute): target = self.visit(target) value = self.visit(node.value) if value == None: value = "None" return "{0} = {1};".format(target, value) definition = node.scopes.find(target.id) if isinstance(target, ast.Name) and defined_before(definition, node): needs_cast = self._needs_cast(target, node.value) target_str = self.visit(target) value = self.visit(node.value) if needs_cast: target_type = self._typename_from_annotation(target) value = self._assign_cast(value, target_type, target.annotation, node.value.rust_annotation) return f"{target_str} = {value};" elif isinstance(node.value, ast.List): count = len(node.value.elts) target = self.visit(target) value = self.visit(node.value) typename = self._typename_from_annotation(node.value) if kw.startswith("pub "): # Use arrays instead of Vec as globals must have fixed size if value.startswith("vec!"): value = value.replace("vec!", "&") element_type = self._default_type if hasattr(node.value, "container_type"): container_type, element_type = node.value.container_type return f"{kw} {target}: &[{element_type}; {count}] = {value};" mut = "mut " if is_mutable(node.scopes, target) else "" if hasattr(node.value, "container_type"): return f"{kw} {target}: &{mut}{typename} = &{mut}{value};" return f"{kw} {target}: {typename} = {value};" elif isinstance(node.value, ast.Set): target = self.visit(target) value = self.visit(node.value) typename = self._typename_from_annotation(node.value) if kw.startswith("pub "): self._usings.add("lazy_static::lazy_static") if "str" in typename: typename = typename.replace("str", "'static str") return ( f"lazy_static! {{ pub static ref {target}: {typename} = {value}; }}" ) mut = "mut " if is_mutable(node.scopes, target) else "" if hasattr(node.value, "container_type"): return f"{kw} {target}: &{mut}{typename} = &{mut}{value};" return f"{kw} {target}: {typename} = {value};" elif isinstance(node.value, ast.Dict): target = self.visit(target) value = self.visit(node.value) typename = self._typename_from_annotation(node.value) if kw.startswith("pub "): if hasattr(node.value, "container_type"): container_type, element_type = node.value.container_type key_typename, value_typename = element_type if key_typename == "&str": key_typename = "&'static str" if value_typename == "&str": value_typename = "&'static str" typename = f"{key_typename}, {value_typename}" return f"lazy_static! {{ pub static ref {target}: HashMap<{typename}> = {value}; }}" mut = "mut " if is_mutable(node.scopes, target) else "" if hasattr(node.value, "container_type"): return f"{kw} {target}: &{mut}{typename} = &{mut}{value};" return f"{kw} {target}: {typename} = {value};" else: typename = self._typename_from_annotation(target) needs_cast = self._needs_cast(target, node.value) target_str = self.visit(target) value = self.visit(node.value) if needs_cast: value = self._assign_cast(value, typename, target.annotation, node.value.annotation) return f"{kw} {target_str}: {typename} = {value};"
def visit_Expr(self, node) -> str: """Writing assert x > 3 is tedious""" ret = super().visit_Expr(node) if is_global(node) and isinstance(node.value, ast.Compare): return f"(assert {ret})" return ret