MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / is_binding_occurrence

Function is_binding_occurrence

internal/cbm/extract_usages.c:1067–1126  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1065}
1066
1067static bool is_binding_occurrence(CBMExtractCtx *ctx, TSNode node, const CBMLangSpec *spec,
1068 WalkState *state) {
1069 const CBMOccurrenceSpec *occurrence = &occurrence_specs[ctx->language];
1070 if (is_exact_language_binding(ctx, node, state)) {
1071 return true;
1072 }
1073 if (is_policy_binding(ctx, node, occurrence)) {
1074 return true;
1075 }
1076
1077 TSNode current = node;
1078 TSTreeCursor *cursor = reset_occurrence_cursor(state, node);
1079 while (!ts_node_is_null(current)) {
1080 TSNode parent;
1081 const char *field;
1082 if (!occurrence_parent(cursor, current, &parent, &field)) {
1083 break;
1084 }
1085 if (is_value_field(field)) {
1086 return false;
1087 }
1088 /* A declaration container binds its name/pattern, not the symbols used
1089 * by its type annotation. Both TypeScript (`cfg: Config`) and Go
1090 * (`cfg Config`) expose that annotation through the exact `type` field;
1091 * stop before the whole-parameter binding rule can swallow `Config`.
1092 * The emitted occurrence remains an ordinary USAGE, never a callable
1093 * reference merely because the target happens to be a type. */
1094 if (field && strcmp(field, "type") == 0) {
1095 return false;
1096 }
1097
1098 const char *kind = ts_node_type(parent);
1099 if (kind_in_exact_set(kind, common_whole_binding_nodes) ||
1100 kind_in_exact_set(kind, occurrence->whole_binding_nodes)) {
1101 return true;
1102 }
1103
1104 bool variable_container =
1105 spec->variable_node_types && cbm_kind_in_set(parent, spec->variable_node_types);
1106 if (ctx->language == CBM_LANG_ELIXIR && strcmp(kind, "binary_operator") == 0) {
1107 variable_container = elixir_binary_operator_binds(ctx, parent);
1108 }
1109 bool declared_container =
1110 kind_in_exact_set(kind, field_binding_nodes) ||
1111 (spec->function_node_types && cbm_kind_in_set(parent, spec->function_node_types)) ||
1112 (spec->class_node_types && cbm_kind_in_set(parent, spec->class_node_types)) ||
1113 (spec->field_node_types && cbm_kind_in_set(parent, spec->field_node_types)) ||
1114 variable_container;
1115 if (declared_container) {
1116 for (const char *const *binding_field = binding_fields; *binding_field;
1117 binding_field++) {
1118 if (field_contains_node(parent, *binding_field, node)) {
1119 return true;
1120 }
1121 }
1122 }
1123 current = parent;
1124 }

Callers 2

try_emit_usageFunction · 0.85
handle_usagesFunction · 0.85

Calls 9

is_policy_bindingFunction · 0.85
reset_occurrence_cursorFunction · 0.85
occurrence_parentFunction · 0.85
is_value_fieldFunction · 0.85
kind_in_exact_setFunction · 0.85
cbm_kind_in_setFunction · 0.85
field_contains_nodeFunction · 0.85

Tested by

no test coverage detected