| 1477 | } |
| 1478 | |
| 1479 | static TSNode call_reference_candidate_site(CBMExtractCtx *ctx, TSNode node, const char *name, |
| 1480 | WalkState *state) { |
| 1481 | if (!ctx || !name || !language_may_stamp_exact_callable_value_candidate(ctx->language)) { |
| 1482 | return (TSNode){0}; |
| 1483 | } |
| 1484 | const char *kind = ts_node_type(node); |
| 1485 | TSTreeCursor *cursor = reset_occurrence_cursor(state, node); |
| 1486 | TSNode parent = {0}; |
| 1487 | const char *parent_field = NULL; |
| 1488 | if (!cursor) { |
| 1489 | usage_slow_parent_fallback_test_note(); |
| 1490 | parent = ts_node_parent(node); |
| 1491 | } else { |
| 1492 | (void)occurrence_parent(cursor, node, &parent, &parent_field); |
| 1493 | } |
| 1494 | bool ts_family = ctx->language == CBM_LANG_JAVASCRIPT || ctx->language == CBM_LANG_TYPESCRIPT || |
| 1495 | ctx->language == CBM_LANG_TSX; |
| 1496 | if (ts_family && strcmp(kind, "property_identifier") == 0 && !ts_node_is_null(parent) && |
| 1497 | strcmp(ts_node_type(parent), "member_expression") == 0) { |
| 1498 | TSNode property = ts_node_child_by_field_name(parent, TS_FIELD("property")); |
| 1499 | TSNode arguments = {0}; |
| 1500 | const char *member_field = NULL; |
| 1501 | if (cursor) { |
| 1502 | (void)occurrence_parent(cursor, parent, &arguments, &member_field); |
| 1503 | } else { |
| 1504 | usage_slow_parent_fallback_test_note(); |
| 1505 | arguments = ts_node_parent(parent); |
| 1506 | } |
| 1507 | return !ts_node_is_null(property) && ts_node_eq(property, node) && |
| 1508 | !ts_node_is_null(arguments) && |
| 1509 | strcmp(ts_node_type(arguments), "arguments") == 0 |
| 1510 | ? node |
| 1511 | : (TSNode){0}; |
| 1512 | } |
| 1513 | if (ctx->language == CBM_LANG_PYTHON && strcmp(kind, "identifier") == 0 && |
| 1514 | !ts_node_is_null(parent) && strcmp(ts_node_type(parent), "attribute") == 0) { |
| 1515 | TSNode attribute = ts_node_child_by_field_name(parent, TS_FIELD("attribute")); |
| 1516 | return !ts_node_is_null(attribute) && ts_node_eq(attribute, node) |
| 1517 | ? python_direct_callable_attribute_site(parent) |
| 1518 | : (TSNode){0}; |
| 1519 | } |
| 1520 | if (ctx->language == CBM_LANG_GO && strcmp(kind, "field_identifier") == 0 && |
| 1521 | !ts_node_is_null(parent) && strcmp(ts_node_type(parent), "selector_expression") == 0) { |
| 1522 | TSNode field = ts_node_child_by_field_name(parent, TS_FIELD("field")); |
| 1523 | return !ts_node_is_null(field) && ts_node_eq(field, node) && |
| 1524 | (cursor ? is_direct_argument_value_cursor(parent, cursor) |
| 1525 | : is_direct_argument_value(parent)) |
| 1526 | ? parent |
| 1527 | : (TSNode){0}; |
| 1528 | } |
| 1529 | if (ctx->language == CBM_LANG_RUST && strcmp(kind, "scoped_identifier") == 0) { |
| 1530 | return is_direct_argument_value_walk(node, state) ? node : (TSNode){0}; |
| 1531 | } |
| 1532 | if (ctx->language == CBM_LANG_CSHARP) { |
| 1533 | return csharp_callable_value_site(node); |
| 1534 | } |
| 1535 | if (strcmp(kind, "identifier") != 0 && strcmp(kind, "simple_identifier") != 0) { |
| 1536 | return (TSNode){0}; |
no test coverage detected