* Handle Pascal-specific AST structures. * Returns true if the node was fully handled and children should be skipped.
(node: SyntaxNode)
| 5248 | * Returns true if the node was fully handled and children should be skipped. |
| 5249 | */ |
| 5250 | private visitPascalNode(node: SyntaxNode): boolean { |
| 5251 | const nodeType = node.type; |
| 5252 | |
| 5253 | // Unit/Program/Library → module node |
| 5254 | if (nodeType === 'unit' || nodeType === 'program' || nodeType === 'library') { |
| 5255 | const moduleNameNode = node.namedChildren.find( |
| 5256 | (c: SyntaxNode) => c.type === 'moduleName' |
| 5257 | ); |
| 5258 | const name = moduleNameNode ? getNodeText(moduleNameNode, this.source) : ''; |
| 5259 | // Fallback to filename without extension if module name is empty |
| 5260 | const moduleName = name || path.basename(this.filePath).replace(/\.[^.]+$/, ''); |
| 5261 | this.createNode('module', moduleName, node); |
| 5262 | // Continue visiting children (interface/implementation sections) |
| 5263 | for (let i = 0; i < node.namedChildCount; i++) { |
| 5264 | const child = node.namedChild(i); |
| 5265 | if (child) this.visitNode(child); |
| 5266 | } |
| 5267 | return true; |
| 5268 | } |
| 5269 | |
| 5270 | // declType wraps declClass/declIntf/declEnum/type-alias |
| 5271 | // The name lives on declType, the inner node determines the kind |
| 5272 | if (nodeType === 'declType') { |
| 5273 | this.extractPascalDeclType(node); |
| 5274 | return true; |
| 5275 | } |
| 5276 | |
| 5277 | // declUses → import nodes for each unit name |
| 5278 | if (nodeType === 'declUses') { |
| 5279 | this.extractPascalUses(node); |
| 5280 | return true; |
| 5281 | } |
| 5282 | |
| 5283 | // declConsts → container; visit children for individual declConst |
| 5284 | if (nodeType === 'declConsts') { |
| 5285 | for (let i = 0; i < node.namedChildCount; i++) { |
| 5286 | const child = node.namedChild(i); |
| 5287 | if (child?.type === 'declConst') { |
| 5288 | this.extractPascalConst(child); |
| 5289 | } |
| 5290 | } |
| 5291 | return true; |
| 5292 | } |
| 5293 | |
| 5294 | // declConst at top level (outside declConsts) |
| 5295 | if (nodeType === 'declConst') { |
| 5296 | this.extractPascalConst(node); |
| 5297 | return true; |
| 5298 | } |
| 5299 | |
| 5300 | // declTypes → container for type declarations |
| 5301 | if (nodeType === 'declTypes') { |
| 5302 | for (let i = 0; i < node.namedChildCount; i++) { |
| 5303 | const child = node.namedChild(i); |
| 5304 | if (child) this.visitNode(child); |
| 5305 | } |
| 5306 | return true; |
| 5307 | } |
no test coverage detected