mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-07 02:58:02 +00:00
fix(cpp): C++ header support, inline methods, adaptive bufferSize
- fix(utils): map .h to C++ (superset of C, handles both pure-C and C++ headers) - feat(cpp-queries): add typedef, union, macro, declaration (prototype) patterns that are common in C/C++ headers — CPP_QUERIES was missing these vs C_QUERIES - feat(cpp): capture inline method bodies inside class (function_definition directly inside field_declaration_list, name is field_identifier not identifier) - fix(parse-worker,call-processor): handle field_identifier and operator_name inner declarator types in findEnclosingFunctionId — inline class methods with bodies were producing CALLS from null (fell through to File nodes) - fix(buffer): adaptive bufferSize = max(2×fileSize, 512KB), capped at 32MB Previous 256KB fixed limit silently skipped any file > ~200KB (imgui.h 411KB, imgui.cpp 931KB, etc.). Silent parse failures caused 0 nodes for large files. Results on test repos after this commit: - tmux (C): 14,087 nodes, 23,196 edges, 300 flows (was 14,008 / 22,686) - imgui (C++): 4,896 nodes, 10,286 edges, 300 flows (was 2,658 / 5,476 / 220) - ShareX (C#): 16,265 nodes, 31,319 edges, 300 flows (unchanged, correct) - curl (C): 28,355 nodes, 53,946 edges, 300 flows (verified)
This commit is contained in:
parent
355e4b36cf
commit
473cbeb92f
5 changed files with 51 additions and 7 deletions
|
|
@ -101,6 +101,14 @@ const findEnclosingFunction = (
|
|||
innerDecl.children?.find((c: any) => c.type === 'identifier');
|
||||
funcName = nameIdent?.text;
|
||||
label = 'Method'; // qualified_identifier => registered as Method
|
||||
} else if (innerDecl?.type === 'field_identifier') {
|
||||
// C++ inline method with body inside class: void myMethod() { ... }
|
||||
funcName = innerDecl.text;
|
||||
label = 'Method';
|
||||
} else if (innerDecl?.type === 'operator_name') {
|
||||
// C++ operator overload inside class body: operator[]
|
||||
funcName = innerDecl.text;
|
||||
label = 'Method';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,7 +311,10 @@ const processParsingSequential = async (
|
|||
|
||||
let tree;
|
||||
try {
|
||||
tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 256 });
|
||||
// bufferSize must be >= file size. Use 2× file size, minimum 512KB, maximum 32MB.
|
||||
const fileSizeBytes = Buffer.byteLength(file.content, 'utf8');
|
||||
const bufSize = Math.min(Math.max(fileSizeBytes * 2, 512 * 1024), 32 * 1024 * 1024);
|
||||
tree = parser.parse(file.content, undefined, { bufferSize: bufSize });
|
||||
} catch (parseError) {
|
||||
console.warn(`Skipping unparseable file: ${file.path}`);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -228,13 +228,31 @@ export const CPP_QUERIES = `
|
|||
(namespace_definition name: (namespace_identifier) @name) @definition.namespace
|
||||
(enum_specifier name: (type_identifier) @name) @definition.enum
|
||||
|
||||
; Typedefs and unions (common in C-style headers and mixed C/C++ code)
|
||||
(type_definition declarator: (type_identifier) @name) @definition.typedef
|
||||
(union_specifier name: (type_identifier) @name) @definition.union
|
||||
|
||||
; Macros
|
||||
(preproc_function_def name: (identifier) @name) @definition.macro
|
||||
(preproc_def name: (identifier) @name) @definition.macro
|
||||
|
||||
; Functions & Methods
|
||||
(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
||||
(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method
|
||||
; Function declarations / prototypes (common in headers)
|
||||
(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
||||
|
||||
; Inline class methods (defined inside the class body)
|
||||
; Inline class method declarations (inside class body, no body: void Foo();)
|
||||
(field_declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.method
|
||||
|
||||
; Inline class method definitions (inside class body, with body: void Foo() { ... })
|
||||
; The function_definition is a direct child of field_declaration_list, not wrapped in field_declaration.
|
||||
; Name uses field_identifier (regular methods) or identifier (constructors) or operator_name (operators).
|
||||
(field_declaration_list
|
||||
(function_definition
|
||||
declarator: (function_declarator
|
||||
declarator: [(field_identifier) (identifier) (operator_name)] @name))) @definition.method
|
||||
|
||||
; Templates
|
||||
(template_declaration (class_specifier name: (type_identifier) @name)) @definition.template
|
||||
(template_declaration (function_definition declarator: (function_declarator declarator: (identifier) @name))) @definition.template
|
||||
|
|
|
|||
|
|
@ -37,11 +37,13 @@ export const getLanguageFromFilename = (filename: string): SupportedLanguages |
|
|||
if (filename.endsWith('.py')) return SupportedLanguages.Python;
|
||||
// Java
|
||||
if (filename.endsWith('.java')) return SupportedLanguages.Java;
|
||||
// C (source and headers)
|
||||
if (filename.endsWith('.c') || filename.endsWith('.h')) return SupportedLanguages.C;
|
||||
// C++ (all common extensions)
|
||||
// C source files
|
||||
if (filename.endsWith('.c')) return SupportedLanguages.C;
|
||||
// C++ (all common extensions, including .h)
|
||||
// .h is parsed as C++ because tree-sitter-cpp is a strict superset of C, so pure-C
|
||||
// headers parse correctly, and C++ headers (classes, templates) are handled properly.
|
||||
if (filename.endsWith('.cpp') || filename.endsWith('.cc') || filename.endsWith('.cxx') ||
|
||||
filename.endsWith('.hpp') || filename.endsWith('.hxx') || filename.endsWith('.hh')) return SupportedLanguages.CPlusPlus;
|
||||
filename.endsWith('.h') || filename.endsWith('.hpp') || filename.endsWith('.hxx') || filename.endsWith('.hh')) return SupportedLanguages.CPlusPlus;
|
||||
// C#
|
||||
if (filename.endsWith('.cs')) return SupportedLanguages.CSharp;
|
||||
// Go
|
||||
|
|
|
|||
|
|
@ -353,6 +353,16 @@ const findEnclosingFunctionId = (node: any, filePath: string): string | null =>
|
|||
innerDecl.children?.find((c: any) => c.type === 'identifier');
|
||||
funcName = nameIdent?.text;
|
||||
label = 'Method'; // qualified_identifier => registered as Method
|
||||
} else if (innerDecl?.type === 'field_identifier') {
|
||||
// C++ inline method with body inside class: void myMethod() { ... }
|
||||
// The function_definition is a direct child of field_declaration_list.
|
||||
// Name node is field_identifier, registered as 'Method'.
|
||||
funcName = innerDecl.text;
|
||||
label = 'Method';
|
||||
} else if (innerDecl?.type === 'operator_name') {
|
||||
// C++ operator overload inside class body: operator[]
|
||||
funcName = innerDecl.text;
|
||||
label = 'Method';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1166,7 +1176,10 @@ const processFileGroup = (
|
|||
|
||||
let tree;
|
||||
try {
|
||||
tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 256 });
|
||||
// bufferSize must be >= file size. Use 2× file size, minimum 512KB, maximum 32MB.
|
||||
const fileSizeBytes = Buffer.byteLength(file.content, 'utf8');
|
||||
const bufSize = Math.min(Math.max(fileSizeBytes * 2, 512 * 1024), 32 * 1024 * 1024);
|
||||
tree = parser.parse(file.content, undefined, { bufferSize: bufSize });
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue