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

Function is_binding_occurrence

internal/cbm/extract_usages.c:1097–1156  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1095}
1096
1097static bool is_binding_occurrence(CBMExtractCtx *ctx, TSNode node, const CBMLangSpec *spec,
1098 WalkState *state) {
1099 const CBMOccurrenceSpec *occurrence = &occurrence_specs[ctx->language];
1100 if (is_exact_language_binding(ctx, node, state)) {
1101 return true;
1102 }
1103 if (is_policy_binding(ctx, node, occurrence)) {
1104 return true;
1105 }
1106
1107 TSNode current = node;
1108 TSTreeCursor *cursor = reset_occurrence_cursor(state, node);
1109 while (!ts_node_is_null(current)) {
1110 TSNode parent;
1111 const char *field;
1112 if (!occurrence_parent(cursor, current, &parent, &field)) {
1113 break;
1114 }
1115 if (is_value_field(field)) {
1116 return false;
1117 }
1118 /* A declaration container binds its name/pattern, not the symbols used
1119 * by its type annotation. Both TypeScript (`cfg: Config`) and Go
1120 * (`cfg Config`) expose that annotation through the exact `type` field;
1121 * stop before the whole-parameter binding rule can swallow `Config`.
1122 * The emitted occurrence remains an ordinary USAGE, never a callable
1123 * reference merely because the target happens to be a type. */
1124 if (field && strcmp(field, "type") == 0) {
1125 return false;
1126 }
1127
1128 const char *kind = ts_node_type(parent);
1129 if (kind_in_exact_set(kind, common_whole_binding_nodes) ||
1130 kind_in_exact_set(kind, occurrence->whole_binding_nodes)) {
1131 return true;
1132 }
1133
1134 bool variable_container =
1135 spec->variable_node_types && cbm_kind_in_set(parent, spec->variable_node_types);
1136 if (ctx->language == CBM_LANG_ELIXIR && strcmp(kind, "binary_operator") == 0) {
1137 variable_container = elixir_binary_operator_binds(ctx, parent);
1138 }
1139 bool declared_container =
1140 kind_in_exact_set(kind, field_binding_nodes) ||
1141 (spec->function_node_types && cbm_kind_in_set(parent, spec->function_node_types)) ||
1142 (spec->class_node_types && cbm_kind_in_set(parent, spec->class_node_types)) ||
1143 (spec->field_node_types && cbm_kind_in_set(parent, spec->field_node_types)) ||
1144 variable_container;
1145 if (declared_container) {
1146 for (const char *const *binding_field = binding_fields; *binding_field;
1147 binding_field++) {
1148 if (field_contains_node(parent, *binding_field, node)) {
1149 return true;
1150 }
1151 }
1152 }
1153 current = parent;
1154 }

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