Exemplo n.º 1
0
 def types_from_Compare(self, node):
     # comparison: `x < y`
     if isinstance(node.op, (vy_ast.In, vy_ast.NotIn)):
         # x in y
         left = self.get_possible_types_from_node(node.left)
         right = self.get_possible_types_from_node(node.right)
         if next((i for i in left if isinstance(i, ArrayDefinition)),
                 False):
             raise InvalidOperation(
                 "Left operand in membership comparison cannot be Array type",
                 node.left,
             )
         if next((i for i in right if not isinstance(i, ArrayDefinition)),
                 False):
             raise InvalidOperation(
                 "Right operand must be Array for membership comparison",
                 node.right)
         types_list = [
             i for i in left
             if _is_type_in_list(i, [i.value_type for i in right])
         ]
         if not types_list:
             raise TypeMismatch(
                 "Cannot perform membership comparison between dislike types",
                 node)
     else:
         types_list = get_common_types(node.left, node.right)
         _validate_op(node, types_list, "validate_comparator")
     return [BoolDefinition()]
Exemplo n.º 2
0
 def visit_If(self, node):
     validate_expected_type(node.test, BoolDefinition())
     with self.namespace.enter_scope():
         for n in node.body:
             self.visit(n)
     with self.namespace.enter_scope():
         for n in node.orelse:
             self.visit(n)
Exemplo n.º 3
0
    def visit_Assert(self, node):
        if node.msg:
            _validate_revert_reason(node.msg)

        try:
            validate_expected_type(node.test, BoolDefinition())
        except InvalidType:
            raise InvalidType("Assertion test value must be a boolean",
                              node.test)
Exemplo n.º 4
0
    def types_from_Compare(self, node):
        # comparisons, e.g. `x < y`

        # TODO fixme circular import
        from vyper.semantics.types.user.enum import EnumDefinition

        if isinstance(node.op, (vy_ast.In, vy_ast.NotIn)):
            # x in y
            left = self.get_possible_types_from_node(node.left)
            right = self.get_possible_types_from_node(node.right)
            if any(isinstance(t, EnumDefinition) for t in left):
                types_list = get_common_types(node.left, node.right)
                _validate_op(node, types_list, "validate_comparator")
                return [BoolDefinition()]

            if any(isinstance(i, ArrayDefinition) for i in left):
                raise InvalidOperation(
                    "Left operand in membership comparison cannot be Array type",
                    node.left)
            if any(not isinstance(i, (DynamicArrayDefinition, ArrayDefinition))
                   for i in right):
                raise InvalidOperation(
                    "Right operand must be Array for membership comparison",
                    node.right)
            types_list = [
                i for i in left
                if _is_type_in_list(i, [i.value_type for i in right])
            ]
            if not types_list:
                raise TypeMismatch(
                    "Cannot perform membership comparison between dislike types",
                    node)
        else:
            types_list = get_common_types(node.left, node.right)
            _validate_op(node, types_list, "validate_comparator")
        return [BoolDefinition()]
Exemplo n.º 5
0
    def __init__(
        self,
        name: str,
        arguments: OrderedDict,
        # TODO rename to something like positional_args, keyword_args
        min_arg_count: int,
        max_arg_count: int,
        return_type: Optional[BaseTypeDefinition],
        function_visibility: FunctionVisibility,
        state_mutability: StateMutability,
        nonreentrant: Optional[str] = None,
    ) -> None:
        super().__init__(
            # A function definition type only exists while compiling
            DataLocation.UNSET,
            # A function definition type is immutable once created
            is_constant=True,
            # A function definition type is public if it's visibility is public
            is_public=(function_visibility == FunctionVisibility.EXTERNAL),
        )
        self.name = name
        self.arguments = arguments
        self.min_arg_count = min_arg_count
        self.max_arg_count = max_arg_count
        self.return_type = return_type
        self.kwarg_keys = []
        if min_arg_count < max_arg_count:
            self.kwarg_keys = list(self.arguments)[min_arg_count:]
        self.visibility = function_visibility
        self.mutability = state_mutability
        self.nonreentrant = nonreentrant

        # a list of internal functions this function calls
        self.called_functions: Set["ContractFunction"] = set()

        # special kwargs that are allowed in call site
        self.call_site_kwargs = {
            "gas":
            KwargSettings(Uint256Definition(), "gas"),
            "value":
            KwargSettings(Uint256Definition(), 0),
            "skip_contract_check":
            KwargSettings(BoolDefinition(), False, require_literal=True),
            "default_return_value":
            KwargSettings(return_type, None),
        }
Exemplo n.º 6
0
    def fetch_call_return(self,
                          node: vy_ast.Call) -> Optional[BaseTypeDefinition]:
        if node.get(
                "func.value.id"
        ) == "self" and self.visibility == FunctionVisibility.EXTERNAL:
            raise CallViolation("Cannnot call external functions via 'self'",
                                node)

        # for external calls, include gas and value as optional kwargs
        kwarg_keys = self.kwarg_keys.copy()
        if node.get("func.value.id") != "self":
            kwarg_keys += ["gas", "value", "skip_contract_check"]
        validate_call_args(node, (self.min_arg_count, self.max_arg_count),
                           kwarg_keys)

        if self.mutability < StateMutability.PAYABLE:
            kwarg_node = next((k for k in node.keywords if k.arg == "value"),
                              None)
            if kwarg_node is not None:
                raise CallViolation(
                    "Cannnot send ether to nonpayable function", kwarg_node)

        for arg, expected in zip(node.args, self.arguments.values()):
            validate_expected_type(arg, expected)

        for kwarg in node.keywords:
            if kwarg.arg in ("gas", "value"):
                validate_expected_type(kwarg.value, Uint256Definition())
            elif kwarg.arg in ("skip_contract_check"):
                validate_expected_type(kwarg.value, BoolDefinition())
                if not isinstance(kwarg.value, vy_ast.NameConstant):
                    raise InvalidType(
                        "skip_contract_check must be literal bool",
                        kwarg.value)
            else:
                validate_expected_type(kwarg.arg, kwarg.value)

        return self.return_type
Exemplo n.º 7
0
 def types_from_BoolOp(self, node):
     # boolean operation: `x and y`
     types_list = get_common_types(*node.values)
     _validate_op(node, types_list, "validate_boolean_op")
     return [BoolDefinition()]