Find the wrapper child that holds annotations/attributes for languages where they are nested under an intermediate node rather than being a prev-sibling: Java/Kotlin/C#/Swift → `modifiers` (contains annotation/attribute) PHP 8 → `attribute_list` (contains attribute_group) Returns a null node when the language has no such wrapper.
| 1730 | // PHP 8 → `attribute_list` (contains attribute_group) |
| 1731 | // Returns a null node when the language has no such wrapper. |
| 1732 | static TSNode find_jvm_modifiers(TSNode node, CBMLanguage lang) { |
| 1733 | TSNode null_node = {0}; |
| 1734 | const char *wrapper = NULL; |
| 1735 | switch (lang) { |
| 1736 | case CBM_LANG_JAVA: |
| 1737 | case CBM_LANG_KOTLIN: |
| 1738 | case CBM_LANG_SWIFT: |
| 1739 | wrapper = "modifiers"; |
| 1740 | break; |
| 1741 | case CBM_LANG_CSHARP: |
| 1742 | case CBM_LANG_PHP: |
| 1743 | /* C# attributes live in an `attribute_list` child (modifiers like |
| 1744 | * `public` are separate `modifier` nodes); PHP 8 likewise nests |
| 1745 | * `attribute_group` under `attribute_list`. */ |
| 1746 | wrapper = "attribute_list"; |
| 1747 | break; |
| 1748 | default: |
| 1749 | return null_node; |
| 1750 | } |
| 1751 | TSNode w = ts_node_child_by_field_name(node, wrapper, (uint32_t)strlen(wrapper)); |
| 1752 | if (ts_node_is_null(w)) { |
| 1753 | w = cbm_find_child_by_kind(node, wrapper); |
| 1754 | } |
| 1755 | return w; |
| 1756 | } |
| 1757 | |
| 1758 | // Count direct children of `node` that are decorator/annotation nodes (used by |
| 1759 | // languages like Scala where the annotation is a direct child of the def node). |
no test coverage detected