* Resolve a Scala type node to its base type NAME for name-matching — unwrapping * `generic_type` (`Monoid[Int]` → `Monoid`), taking the last segment of a * qualified `stable_type_identifier` (`cats.Functor` → `Functor`), and falling * back to a descendant `type_identifier`. Returns null for non-
(node: SyntaxNode | null, source: string)
| 174 | * Shared by Scala inheritance and type-reference extraction. |
| 175 | */ |
| 176 | function scalaBaseTypeName(node: SyntaxNode | null, source: string): string | null { |
| 177 | if (!node) return null; |
| 178 | switch (node.type) { |
| 179 | case 'type_identifier': |
| 180 | case 'identifier': |
| 181 | return getNodeText(node, source); |
| 182 | case 'generic_type': |
| 183 | // `<base> type_arguments` — the base type is the first named child. |
| 184 | return scalaBaseTypeName(node.namedChild(0), source); |
| 185 | case 'stable_type_identifier': |
| 186 | case 'stable_identifier': { |
| 187 | // Qualified `a.b.C` — match on the simple (last) segment. |
| 188 | const ids = node.namedChildren.filter( |
| 189 | (c: SyntaxNode) => c.type === 'type_identifier' || c.type === 'identifier' |
| 190 | ); |
| 191 | const last = ids[ids.length - 1]; |
| 192 | return last ? getNodeText(last, source) : null; |
| 193 | } |
| 194 | default: { |
| 195 | const id = node.namedChildren.find((c: SyntaxNode) => c.type === 'type_identifier'); |
| 196 | return id ? getNodeText(id, source) : null; |
| 197 | } |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | /** |
| 202 | * Resolve the declared identifier inside a C declarator. A `declaration`'s |
no test coverage detected