slither.slithir.operations.internal_call

 1from typing import Any, Union, Tuple, List, Optional
 2from slither.core.declarations import Modifier
 3from slither.core.declarations.function import Function
 4from slither.core.declarations.function_contract import FunctionContract
 5from slither.slithir.operations.call import Call
 6from slither.slithir.operations.lvalue import OperationWithLValue
 7from slither.slithir.variables.constant import Constant
 8from slither.slithir.variables.temporary import TemporaryVariable
 9from slither.slithir.variables.temporary_ssa import TemporaryVariableSSA
10from slither.slithir.variables.tuple import TupleVariable
11from slither.slithir.variables.tuple_ssa import TupleVariableSSA
12
13
14class InternalCall(Call, OperationWithLValue):  # pylint: disable=too-many-instance-attributes
15    def __init__(
16        self,
17        function: Union[Function, Tuple[str, str]],
18        nbr_arguments: int,
19        result: Optional[
20            Union[TupleVariableSSA, TemporaryVariableSSA, TupleVariable, TemporaryVariable]
21        ],
22        type_call: str,
23        names: Optional[List[str]] = None,
24    ) -> None:
25        # pylint: disable=too-many-arguments
26        """
27        #### Parameters
28        names -
29            For calls of the form f({argName1 : arg1, ...}), the names of parameters listed in call order.
30            Otherwise, None.
31        """
32        super().__init__(names=names)
33        self._contract_name = ""
34        if isinstance(function, Function):
35            self._function: Optional[Function] = function
36            self._function_name = function.name
37            if isinstance(function, FunctionContract):
38                self._contract_name = function.contract_declarer.name
39        else:
40            self._function = None
41            self._function_name, self._contract_name = function
42        # self._contract = contract
43        self._nbr_arguments = nbr_arguments
44        self._type_call = type_call
45        self._lvalue = result
46        # function_candidates is only used as an helper to retrieve the "function" object
47        # For top level function called through a import renamed
48        # See SolidityImportPlaceHolder usages
49        self.function_candidates: Optional[List[Function]] = None
50
51    @property
52    def read(self) -> List[Any]:
53        return list(self._unroll(self.arguments))
54
55    @property
56    def function(self) -> Optional[Function]:
57        return self._function
58
59    @function.setter
60    def function(self, f):
61        self._function = f
62
63    @property
64    def function_name(self) -> Constant:
65        return self._function_name
66
67    @property
68    def contract_name(self) -> str:
69        return self._contract_name
70
71    @property
72    def nbr_arguments(self) -> int:
73        return self._nbr_arguments
74
75    @property
76    def type_call(self) -> str:
77        return self._type_call
78
79    @property
80    def is_modifier_call(self):
81        """
82        Check if the destination is a modifier
83        :return: bool
84        """
85        return isinstance(self.function, Modifier)
86
87    def __str__(self):
88        args = [str(a) for a in self.arguments]
89        if not self.lvalue:
90            lvalue = ""
91        elif isinstance(self.lvalue.type, (list,)):
92            lvalue = f"{self.lvalue}({','.join(str(x) for x in self.lvalue.type)}) = "
93        else:
94            lvalue = f"{self.lvalue}({self.lvalue.type}) = "
95        if self.is_modifier_call:
96            txt = "{}MODIFIER_CALL, {}({})"
97        else:
98            txt = "{}INTERNAL_CALL, {}({})"
99        return txt.format(lvalue, self.function.canonical_name, ",".join(args))
 15class InternalCall(Call, OperationWithLValue):  # pylint: disable=too-many-instance-attributes
 16    def __init__(
 17        self,
 18        function: Union[Function, Tuple[str, str]],
 19        nbr_arguments: int,
 20        result: Optional[
 21            Union[TupleVariableSSA, TemporaryVariableSSA, TupleVariable, TemporaryVariable]
 22        ],
 23        type_call: str,
 24        names: Optional[List[str]] = None,
 25    ) -> None:
 26        # pylint: disable=too-many-arguments
 27        """
 28        #### Parameters
 29        names -
 30            For calls of the form f({argName1 : arg1, ...}), the names of parameters listed in call order.
 31            Otherwise, None.
 32        """
 33        super().__init__(names=names)
 34        self._contract_name = ""
 35        if isinstance(function, Function):
 36            self._function: Optional[Function] = function
 37            self._function_name = function.name
 38            if isinstance(function, FunctionContract):
 39                self._contract_name = function.contract_declarer.name
 40        else:
 41            self._function = None
 42            self._function_name, self._contract_name = function
 43        # self._contract = contract
 44        self._nbr_arguments = nbr_arguments
 45        self._type_call = type_call
 46        self._lvalue = result
 47        # function_candidates is only used as an helper to retrieve the "function" object
 48        # For top level function called through a import renamed
 49        # See SolidityImportPlaceHolder usages
 50        self.function_candidates: Optional[List[Function]] = None
 51
 52    @property
 53    def read(self) -> List[Any]:
 54        return list(self._unroll(self.arguments))
 55
 56    @property
 57    def function(self) -> Optional[Function]:
 58        return self._function
 59
 60    @function.setter
 61    def function(self, f):
 62        self._function = f
 63
 64    @property
 65    def function_name(self) -> Constant:
 66        return self._function_name
 67
 68    @property
 69    def contract_name(self) -> str:
 70        return self._contract_name
 71
 72    @property
 73    def nbr_arguments(self) -> int:
 74        return self._nbr_arguments
 75
 76    @property
 77    def type_call(self) -> str:
 78        return self._type_call
 79
 80    @property
 81    def is_modifier_call(self):
 82        """
 83        Check if the destination is a modifier
 84        :return: bool
 85        """
 86        return isinstance(self.function, Modifier)
 87
 88    def __str__(self):
 89        args = [str(a) for a in self.arguments]
 90        if not self.lvalue:
 91            lvalue = ""
 92        elif isinstance(self.lvalue.type, (list,)):
 93            lvalue = f"{self.lvalue}({','.join(str(x) for x in self.lvalue.type)}) = "
 94        else:
 95            lvalue = f"{self.lvalue}({self.lvalue.type}) = "
 96        if self.is_modifier_call:
 97            txt = "{}MODIFIER_CALL, {}({})"
 98        else:
 99            txt = "{}INTERNAL_CALL, {}({})"
100        return txt.format(lvalue, self.function.canonical_name, ",".join(args))

Operation with a lvalue

InternalCall( function: Union[slither.core.declarations.function.Function, Tuple[str, str]], nbr_arguments: int, result: Union[slither.slithir.variables.tuple_ssa.TupleVariableSSA, slither.slithir.variables.temporary_ssa.TemporaryVariableSSA, slither.slithir.variables.tuple.TupleVariable, slither.slithir.variables.temporary.TemporaryVariable, NoneType], type_call: str, names: Union[List[str], NoneType] = None)
16    def __init__(
17        self,
18        function: Union[Function, Tuple[str, str]],
19        nbr_arguments: int,
20        result: Optional[
21            Union[TupleVariableSSA, TemporaryVariableSSA, TupleVariable, TemporaryVariable]
22        ],
23        type_call: str,
24        names: Optional[List[str]] = None,
25    ) -> None:
26        # pylint: disable=too-many-arguments
27        """
28        #### Parameters
29        names -
30            For calls of the form f({argName1 : arg1, ...}), the names of parameters listed in call order.
31            Otherwise, None.
32        """
33        super().__init__(names=names)
34        self._contract_name = ""
35        if isinstance(function, Function):
36            self._function: Optional[Function] = function
37            self._function_name = function.name
38            if isinstance(function, FunctionContract):
39                self._contract_name = function.contract_declarer.name
40        else:
41            self._function = None
42            self._function_name, self._contract_name = function
43        # self._contract = contract
44        self._nbr_arguments = nbr_arguments
45        self._type_call = type_call
46        self._lvalue = result
47        # function_candidates is only used as an helper to retrieve the "function" object
48        # For top level function called through a import renamed
49        # See SolidityImportPlaceHolder usages
50        self.function_candidates: Optional[List[Function]] = None

Parameters

names - For calls of the form f({argName1 : arg1, ...}), the names of parameters listed in call order. Otherwise, None.

function_candidates: Union[List[slither.core.declarations.function.Function], NoneType]
read: List[Any]
52    @property
53    def read(self) -> List[Any]:
54        return list(self._unroll(self.arguments))

Return the list of variables READ

function: Union[slither.core.declarations.function.Function, NoneType]
56    @property
57    def function(self) -> Optional[Function]:
58        return self._function
function_name: slither.slithir.variables.constant.Constant
64    @property
65    def function_name(self) -> Constant:
66        return self._function_name
contract_name: str
68    @property
69    def contract_name(self) -> str:
70        return self._contract_name
nbr_arguments: int
72    @property
73    def nbr_arguments(self) -> int:
74        return self._nbr_arguments
type_call: str
76    @property
77    def type_call(self) -> str:
78        return self._type_call
is_modifier_call
80    @property
81    def is_modifier_call(self):
82        """
83        Check if the destination is a modifier
84        :return: bool
85        """
86        return isinstance(self.function, Modifier)

Check if the destination is a modifier

Returns

bool