Visitor for finding all the types of arguments that each arg is passed to. This is extremely simple minded but might be effective anyways.
| 162 | |
| 163 | |
| 164 | class ArgUseFinder(TraverserVisitor): |
| 165 | """Visitor for finding all the types of arguments that each arg is passed to. |
| 166 | |
| 167 | This is extremely simple minded but might be effective anyways. |
| 168 | """ |
| 169 | |
| 170 | def __init__(self, func: FuncDef, typemap: dict[Expression, Type]) -> None: |
| 171 | self.typemap = typemap |
| 172 | self.arg_types: dict[SymbolNode, list[Type]] = {arg.variable: [] for arg in func.arguments} |
| 173 | |
| 174 | def visit_call_expr(self, o: CallExpr) -> None: |
| 175 | if not any(isinstance(e, RefExpr) and e.node in self.arg_types for e in o.args): |
| 176 | return |
| 177 | |
| 178 | typ = get_proper_type(self.typemap.get(o.callee)) |
| 179 | if not isinstance(typ, CallableType): |
| 180 | return |
| 181 | |
| 182 | formal_to_actual = map_actuals_to_formals( |
| 183 | o.arg_kinds, |
| 184 | o.arg_names, |
| 185 | typ.arg_kinds, |
| 186 | typ.arg_names, |
| 187 | lambda n: AnyType(TypeOfAny.special_form), |
| 188 | ) |
| 189 | |
| 190 | for i, args in enumerate(formal_to_actual): |
| 191 | for arg_idx in args: |
| 192 | arg = o.args[arg_idx] |
| 193 | if isinstance(arg, RefExpr) and arg.node in self.arg_types: |
| 194 | self.arg_types[arg.node].append(typ.arg_types[i]) |
| 195 | |
| 196 | |
| 197 | def get_arg_uses(typemap: dict[Expression, Type], func: FuncDef) -> list[list[Type]]: |
no outgoing calls
no test coverage detected
searching dependent graphs…