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.
This commit is contained in:
@@ -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) {
|
||||||
// Handle complex declarators (C/C++)
|
// Unwrap pointer_declarator(s) for C/C++ pointer return types
|
||||||
if (nameNode.type === 'function_declarator' || nameNode.type === 'declarator') {
|
let resolved = nameNode;
|
||||||
const innerName = getChildByField(nameNode, 'declarator') || nameNode.namedChild(0);
|
while (resolved.type === 'pointer_declarator') {
|
||||||
return innerName ? getNodeText(innerName, source) : getNodeText(nameNode, source);
|
const inner = getChildByField(resolved, 'declarator') || resolved.namedChild(0);
|
||||||
|
if (!inner) break;
|
||||||
|
resolved = inner;
|
||||||
}
|
}
|
||||||
return getNodeText(nameNode, source);
|
// Handle complex declarators (C/C++)
|
||||||
|
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(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++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user