Detect whether a node is a throw node for the given spec. Kotlin special case: this grammar models `throw X(...)` as a `jump_expression` (the same node also covers return/break/continue), NOT a `throw_expression`, so the spec's throw_node_types ("throw_expression") never matches. We treat a Kotlin `jump_expression` as a throw only when its first child is the `throw` keyword, which excludes retur
| 25 | // Kotlin `jump_expression` as a throw only when its first child is the `throw` |
| 26 | // keyword, which excludes return/break/continue without false positives. |
| 27 | static bool is_throw_node(TSNode node, const CBMLangSpec *spec) { |
| 28 | if (cbm_kind_in_set(node, spec->throw_node_types)) { |
| 29 | return true; |
| 30 | } |
| 31 | if (spec->language == CBM_LANG_KOTLIN && strcmp(ts_node_type(node), "jump_expression") == 0) { |
| 32 | uint32_t nc = ts_node_child_count(node); |
| 33 | if (nc > 0 && strcmp(ts_node_type(ts_node_child(node, 0)), "throw") == 0) { |
| 34 | return true; |
| 35 | } |
| 36 | } |
| 37 | return false; |
| 38 | } |
| 39 | |
| 40 | // Resolve exception name from the first meaningful child of a throw/raise node. |
| 41 | static char *resolve_exception_name(CBMArena *a, TSNode throw_node, const char *source) { |
no test coverage detected