Beispiel #1
0
    def parse_AnnAssign(self):
        typ = parse_type(
            self.stmt.annotation,
            sigs=self.context.sigs,
            custom_structs=self.context.structs,
        )
        varname = self.stmt.target.id
        pos = self.context.new_variable(varname, typ)
        if self.stmt.value is None:
            return

        sub = Expr(self.stmt.value, self.context).ir_node

        is_literal_bytes32_assign = (isinstance(sub.typ, ByteArrayType)
                                     and sub.typ.maxlen == 32
                                     and isinstance(typ, BaseType)
                                     and typ.typ == "bytes32"
                                     and sub.typ.is_literal)

        # If bytes[32] to bytes32 assignment rewrite sub as bytes32.
        if is_literal_bytes32_assign:
            sub = IRnode(
                util.bytes_to_int(self.stmt.value.s),
                typ=BaseType("bytes32"),
            )

        variable_loc = IRnode.from_list(pos, typ=typ, location=MEMORY)

        ir_node = make_setter(variable_loc, sub)

        return ir_node
Beispiel #2
0
 def parse_type(self, ast_node):
     return parse_type(ast_node,
                       sigs=self.interface_names,
                       custom_structs=self._structs,
                       enums=self._enums)
Beispiel #3
0
    def from_definition(
        cls,
        func_ast,  # vy_ast.FunctionDef
        sigs=None,  # TODO replace sigs and custom_structs with GlobalContext?
        custom_structs=None,
        interface_def=False,
        constant_override=False,  # CMC 20210907 what does this do?
        is_from_json=False,
    ):
        if custom_structs is None:
            custom_structs = {}

        name = func_ast.name

        args = []
        for arg in func_ast.args.args:
            argname = arg.arg
            argtyp = parse_type(
                arg.annotation,
                sigs,
                custom_structs=custom_structs,
            )

            args.append(FunctionArg(argname, argtyp, arg))

        mutability = "nonpayable"  # Assume nonpayable by default
        nonreentrant_key = None
        is_internal = None

        # Update function properties from decorators
        # NOTE: Can't import enums here because of circular import
        for dec in func_ast.decorator_list:
            if isinstance(dec, vy_ast.Name) and dec.id in ("payable", "view", "pure"):
                mutability = dec.id
            elif isinstance(dec, vy_ast.Name) and dec.id == "internal":
                is_internal = True
            elif isinstance(dec, vy_ast.Name) and dec.id == "external":
                is_internal = False
            elif isinstance(dec, vy_ast.Call) and dec.func.id == "nonreentrant":
                nonreentrant_key = dec.args[0].s

        if constant_override:
            # In case this override is abused, match previous behavior
            if mutability == "payable":
                raise StructureException(f"Function {name} cannot be both constant and payable.")
            mutability = "view"

        # Determine the return type and whether or not it's constant. Expects something
        # of the form:
        # def foo(): ...
        # def foo() -> int128: ...
        # If there is no return type, ie. it's of the form def foo(): ...
        # and NOT def foo() -> type: ..., then it's null
        return_type = None
        if func_ast.returns:
            return_type = parse_type(
                func_ast.returns,
                sigs,
                custom_structs=custom_structs,
            )
            # sanity check: Output type must be canonicalizable
            assert return_type.abi_type.selector_name()

        return cls(
            name,
            args,
            return_type,
            mutability,
            is_internal,
            nonreentrant_key,
            func_ast,
            is_from_json,
        )
Beispiel #4
0
 def parse_type(self, ast_node):
     return parse_type(
         ast_node,
         sigs=self._contracts,
         custom_structs=self._structs,
     )