| 1221 | } |
| 1222 | |
| 1223 | static bool is_write_occurrence(CBMExtractCtx *ctx, TSNode node, const CBMLangSpec *spec, |
| 1224 | WalkState *state) { |
| 1225 | const CBMOccurrenceSpec *occurrence = &occurrence_specs[ctx->language]; |
| 1226 | TSNode current = node; |
| 1227 | TSTreeCursor *cursor = reset_occurrence_cursor(state, node); |
| 1228 | while (!ts_node_is_null(current)) { |
| 1229 | TSNode parent; |
| 1230 | const char *field; |
| 1231 | if (!occurrence_parent(cursor, current, &parent, &field)) { |
| 1232 | break; |
| 1233 | } |
| 1234 | if (is_value_field(field)) { |
| 1235 | return false; |
| 1236 | } |
| 1237 | bool assignment = |
| 1238 | (spec->assignment_node_types && cbm_kind_in_set(parent, spec->assignment_node_types)) || |
| 1239 | kind_in_exact_set(ts_node_type(parent), occurrence->write_nodes); |
| 1240 | if (ctx->language == CBM_LANG_ELIXIR && |
| 1241 | strcmp(ts_node_type(parent), "binary_operator") == 0) { |
| 1242 | assignment = elixir_binary_operator_binds(ctx, parent); |
| 1243 | } |
| 1244 | if (assignment) { |
| 1245 | if (assignment_reads_target(parent)) { |
| 1246 | return false; |
| 1247 | } |
| 1248 | if (ctx->language == CBM_LANG_LINKERSCRIPT && |
| 1249 | strcmp(ts_node_type(parent), "assignment") == 0) { |
| 1250 | /* This grammar's assignment production has no field map. Its |
| 1251 | * first direct child is the lhs, even when that child is the |
| 1252 | * anonymous location-counter token `.`. */ |
| 1253 | return ts_node_child_count(parent) > 0 && |
| 1254 | node_contains(ts_node_child(parent, 0), node); |
| 1255 | } |
| 1256 | TSNode left = ts_node_child_by_field_name(parent, TS_FIELD("left")); |
| 1257 | if (node_contains(left, node) || field_contains_node(parent, "target", node) || |
| 1258 | field_contains_node(parent, "destination", node)) { |
| 1259 | return true; |
| 1260 | } |
| 1261 | return occurrence->first_named_child_is_write && named_child_contains(parent, 0, node); |
| 1262 | } |
| 1263 | current = parent; |
| 1264 | } |
| 1265 | return false; |
| 1266 | } |
| 1267 | |
| 1268 | static bool is_argument_container_kind(const char *kind) { |
| 1269 | return kind && (strcmp(kind, "arguments") == 0 || strcmp(kind, "argument_list") == 0 || |
no test coverage detected