| 1194 | } |
| 1195 | |
| 1196 | static bool is_write_occurrence(CBMExtractCtx *ctx, TSNode node, const CBMLangSpec *spec, |
| 1197 | WalkState *state) { |
| 1198 | const CBMOccurrenceSpec *occurrence = &occurrence_specs[ctx->language]; |
| 1199 | TSNode current = node; |
| 1200 | TSTreeCursor *cursor = reset_occurrence_cursor(state, node); |
| 1201 | while (!ts_node_is_null(current)) { |
| 1202 | TSNode parent; |
| 1203 | const char *field; |
| 1204 | if (!occurrence_parent(cursor, current, &parent, &field)) { |
| 1205 | break; |
| 1206 | } |
| 1207 | if (is_value_field(field)) { |
| 1208 | return false; |
| 1209 | } |
| 1210 | bool assignment = |
| 1211 | (spec->assignment_node_types && cbm_kind_in_set(parent, spec->assignment_node_types)) || |
| 1212 | kind_in_exact_set(ts_node_type(parent), occurrence->write_nodes); |
| 1213 | if (ctx->language == CBM_LANG_ELIXIR && |
| 1214 | strcmp(ts_node_type(parent), "binary_operator") == 0) { |
| 1215 | assignment = elixir_binary_operator_binds(ctx, parent); |
| 1216 | } |
| 1217 | if (assignment) { |
| 1218 | if (assignment_reads_target(parent)) { |
| 1219 | return false; |
| 1220 | } |
| 1221 | if (ctx->language == CBM_LANG_LINKERSCRIPT && |
| 1222 | strcmp(ts_node_type(parent), "assignment") == 0) { |
| 1223 | /* This grammar's assignment production has no field map. Its |
| 1224 | * first direct child is the lhs, even when that child is the |
| 1225 | * anonymous location-counter token `.`. */ |
| 1226 | return ts_node_child_count(parent) > 0 && |
| 1227 | node_contains(ts_node_child(parent, 0), node); |
| 1228 | } |
| 1229 | TSNode left = ts_node_child_by_field_name(parent, TS_FIELD("left")); |
| 1230 | if (node_contains(left, node) || field_contains_node(parent, "target", node) || |
| 1231 | field_contains_node(parent, "destination", node)) { |
| 1232 | return true; |
| 1233 | } |
| 1234 | return occurrence->first_named_child_is_write && named_child_contains(parent, 0, node); |
| 1235 | } |
| 1236 | current = parent; |
| 1237 | } |
| 1238 | return false; |
| 1239 | } |
| 1240 | |
| 1241 | static bool is_argument_container_kind(const char *kind) { |
| 1242 | return kind && (strcmp(kind, "arguments") == 0 || strcmp(kind, "argument_list") == 0 || |
no test coverage detected