Quellcode durchsuchen

feat: Improve C/C++ name extraction and skip forward declarations in struct/enum processing

Addresses C/C++ pointer declarator unwrapping where pointer_declarator nodes need to be resolved to find the actual function/variable name. Adds forward declaration filtering by checking for body field presence before processing struct and enum definitions, preventing extraction of incomplete type declarations.
Colby McHenry vor 2 Monaten
Ursprung
Commit
da248f9a8e
1 geänderte Dateien mit 20 neuen und 8 gelöschten Zeilen
  1. 20 8
      src/extraction/tree-sitter.ts

+ 20 - 8
src/extraction/tree-sitter.ts

@@ -33,12 +33,19 @@ function extractName(node: SyntaxNode, source: string, extractor: LanguageExtrac
   // Try field name first
   // Try field name first
   const nameNode = getChildByField(node, extractor.nameField);
   const nameNode = getChildByField(node, extractor.nameField);
   if (nameNode) {
   if (nameNode) {
+    // Unwrap pointer_declarator(s) for C/C++ pointer return types
+    let resolved = nameNode;
+    while (resolved.type === 'pointer_declarator') {
+      const inner = getChildByField(resolved, 'declarator') || resolved.namedChild(0);
+      if (!inner) break;
+      resolved = inner;
+    }
     // Handle complex declarators (C/C++)
     // Handle complex declarators (C/C++)
-    if (nameNode.type === 'function_declarator' || nameNode.type === 'declarator') {
-      const innerName = getChildByField(nameNode, 'declarator') || nameNode.namedChild(0);
-      return innerName ? getNodeText(innerName, source) : getNodeText(nameNode, source);
+    if (resolved.type === 'function_declarator' || resolved.type === 'declarator') {
+      const innerName = getChildByField(resolved, 'declarator') || resolved.namedChild(0);
+      return innerName ? getNodeText(innerName, source) : getNodeText(resolved, source);
     }
     }
-    return getNodeText(nameNode, source);
+    return getNodeText(resolved, source);
   }
   }
 
 
   // For Dart method_signature, look inside inner signature types
   // For Dart method_signature, look inside inner signature types
@@ -601,6 +608,10 @@ export class TreeSitterExtractor {
   private extractStruct(node: SyntaxNode): void {
   private extractStruct(node: SyntaxNode): void {
     if (!this.extractor) return;
     if (!this.extractor) return;
 
 
+    // Skip forward declarations and type references (no body = not a definition)
+    const body = getChildByField(node, this.extractor.bodyField);
+    if (!body) return;
+
     const name = extractName(node, this.source, this.extractor);
     const name = extractName(node, this.source, this.extractor);
     const docstring = getPrecedingDocstring(node, this.source);
     const docstring = getPrecedingDocstring(node, this.source);
     const visibility = this.extractor.getVisibility?.(node);
     const visibility = this.extractor.getVisibility?.(node);
@@ -618,7 +629,6 @@ export class TreeSitterExtractor {
 
 
     // Push to stack for field extraction
     // Push to stack for field extraction
     this.nodeStack.push(structNode.id);
     this.nodeStack.push(structNode.id);
-    const body = getChildByField(node, this.extractor.bodyField) || node;
     for (let i = 0; i < body.namedChildCount; i++) {
     for (let i = 0; i < body.namedChildCount; i++) {
       const child = body.namedChild(i);
       const child = body.namedChild(i);
       if (child) {
       if (child) {
@@ -634,6 +644,11 @@ export class TreeSitterExtractor {
   private extractEnum(node: SyntaxNode): void {
   private extractEnum(node: SyntaxNode): void {
     if (!this.extractor) return;
     if (!this.extractor) return;
 
 
+    // Skip forward declarations and type references (no body = not a definition)
+    const body = this.extractor.resolveBody?.(node, this.extractor.bodyField)
+      ?? getChildByField(node, this.extractor.bodyField);
+    if (!body) return;
+
     const name = extractName(node, this.source, this.extractor);
     const name = extractName(node, this.source, this.extractor);
     const docstring = getPrecedingDocstring(node, this.source);
     const docstring = getPrecedingDocstring(node, this.source);
     const visibility = this.extractor.getVisibility?.(node);
     const visibility = this.extractor.getVisibility?.(node);
@@ -651,9 +666,6 @@ export class TreeSitterExtractor {
 
 
     // Push to stack and visit body children (enum members, nested types, methods)
     // Push to stack and visit body children (enum members, nested types, methods)
     this.nodeStack.push(enumNode.id);
     this.nodeStack.push(enumNode.id);
-    const body = this.extractor.resolveBody?.(node, this.extractor.bodyField)
-      ?? getChildByField(node, this.extractor.bodyField)
-      ?? node;
 
 
     const memberTypes = this.extractor.enumMemberTypes;
     const memberTypes = this.extractor.enumMemberTypes;
     for (let i = 0; i < body.namedChildCount; i++) {
     for (let i = 0; i < body.namedChildCount; i++) {