| 813 | |
| 814 | @dataclass |
| 815 | class Call(ASTNode): |
| 816 | func: NodeType |
| 817 | args: list |
| 818 | kwargs: dict |
| 819 | taints: dict = field(default_factory=dict) |
| 820 | |
| 821 | def __post_init__(self): |
| 822 | super().__post_init__() |
| 823 | self._orig_args = [None] * len(self.args) |
| 824 | |
| 825 | def __repr__(self): |
| 826 | if len(self.args) == 0 and len(self.kwargs) == 0: |
| 827 | f_args = "" |
| 828 | elif self.args and not self.kwargs: |
| 829 | f_args = f"*{repr(self.args)}" |
| 830 | elif self.kwargs and not self.args: |
| 831 | f_args = f"**{repr(self.kwargs)}" |
| 832 | else: |
| 833 | f_args = f"*{repr(self.args)}, **{repr(self.kwargs)}" |
| 834 | |
| 835 | return f"Call({repr(self.func)})({f_args})" |
| 836 | |
| 837 | def __hash__(self): |
| 838 | h = hash((self.full_name, self.line_no,)) |
| 839 | return h |
| 840 | |
| 841 | def _visit_node(self, context: Context): |
| 842 | if type(self.full_name) == str: |
| 843 | context.call_graph[self.full_name] = self |
| 844 | |
| 845 | for idx in range(len(self.args)): |
| 846 | try: |
| 847 | arg = self.args[idx] |
| 848 | if type(arg) == str: |
| 849 | arg = context.stack[arg] |
| 850 | if arg.line_no is None or arg.line_no != self.line_no: |
| 851 | self._orig_args[idx] = self.args[idx] |
| 852 | self.args[idx] = arg |
| 853 | context.visitor.modified = True |
| 854 | except (TypeError, KeyError): |
| 855 | pass |
| 856 | |
| 857 | context.visit_child( |
| 858 | node=self.args[idx], |
| 859 | replace=partial(self.__replace_arg, idx=idx, visitor=context.visitor), |
| 860 | ) |
| 861 | |
| 862 | for key, value in list(self.kwargs.items()): |
| 863 | try: |
| 864 | if type(value) == str: |
| 865 | target = context.stack[value] |
| 866 | self.kwargs[key] = target |
| 867 | context.visitor.modified = True |
| 868 | except (TypeError, KeyError): |
| 869 | pass |
| 870 | |
| 871 | context.visit_child( |
| 872 | node=self.kwargs[key], |