Generate either a native or Python method call.
(
self,
base: Value,
name: str,
arg_values: list[Value],
result_type: RType | None,
line: int,
arg_kinds: list[ArgKind] | None = None,
arg_names: list[str | None] | None = None,
can_borrow: bool = False,
)
| 1393 | return output_args |
| 1394 | |
| 1395 | def gen_method_call( |
| 1396 | self, |
| 1397 | base: Value, |
| 1398 | name: str, |
| 1399 | arg_values: list[Value], |
| 1400 | result_type: RType | None, |
| 1401 | line: int, |
| 1402 | arg_kinds: list[ArgKind] | None = None, |
| 1403 | arg_names: list[str | None] | None = None, |
| 1404 | can_borrow: bool = False, |
| 1405 | ) -> Value: |
| 1406 | """Generate either a native or Python method call.""" |
| 1407 | # If we have *args, then fallback to Python method call. |
| 1408 | if arg_kinds is not None and any(kind.is_star() for kind in arg_kinds): |
| 1409 | return self.py_method_call(base, name, arg_values, line, arg_kinds, arg_names) |
| 1410 | |
| 1411 | # If the base type is one of ours, do a MethodCall |
| 1412 | fast_name = FAST_PREFIX + name |
| 1413 | if ( |
| 1414 | isinstance(base.type, RInstance) |
| 1415 | and (base.type.class_ir.is_ext_class or base.type.class_ir.has_method(fast_name)) |
| 1416 | and not base.type.class_ir.builtin_base |
| 1417 | ): |
| 1418 | name = name if base.type.class_ir.is_ext_class else fast_name |
| 1419 | if base.type.class_ir.has_method(name): |
| 1420 | decl = base.type.class_ir.method_decl(name) |
| 1421 | if arg_kinds is None: |
| 1422 | assert arg_names is None, "arg_kinds not present but arg_names is" |
| 1423 | arg_kinds = [ARG_POS for _ in arg_values] |
| 1424 | arg_names = [None for _ in arg_values] |
| 1425 | else: |
| 1426 | assert arg_names is not None, "arg_kinds present but arg_names is not" |
| 1427 | |
| 1428 | # Normalize args to positionals. |
| 1429 | assert decl.bound_sig |
| 1430 | arg_values = self.native_args_to_positional( |
| 1431 | arg_values, arg_kinds, arg_names, decl.bound_sig, line |
| 1432 | ) |
| 1433 | return self.add(MethodCall(base, name, arg_values, line)) |
| 1434 | elif base.type.class_ir.has_attr(name): |
| 1435 | function = self.add(GetAttr(base, name, line)) |
| 1436 | return self.py_call( |
| 1437 | function, arg_values, line, arg_kinds=arg_kinds, arg_names=arg_names |
| 1438 | ) |
| 1439 | |
| 1440 | elif isinstance(base.type, RUnion): |
| 1441 | return self.union_method_call( |
| 1442 | base, base.type, name, arg_values, result_type, line, arg_kinds, arg_names |
| 1443 | ) |
| 1444 | |
| 1445 | # Try to do a special-cased method call |
| 1446 | if not arg_kinds or arg_kinds == [ARG_POS] * len(arg_values): |
| 1447 | target = self.translate_special_method_call( |
| 1448 | base, name, arg_values, result_type, line, can_borrow=can_borrow |
| 1449 | ) |
| 1450 | if target: |
| 1451 | return target |
| 1452 |
no test coverage detected