Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions FORK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Maintenance fork

This is FM-Agent's maintenance fork of
[colbymchenry/codegraph](https://github.com/colbymchenry/codegraph).

**Pinned base:** upstream `v1.3.0` (this fork's `main` is reset to that tag).

**Patch on top:**
- **#1211 fix** — the C extractor now blanks macro attributes before a
typedef'd return type (upstream PR
[#1223](https://github.com/colbymchenry/codegraph/pull/1223)), so functions
shaped like `LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)` are indexed
under their real name instead of under the parameter list `(VOID)`.

**Version marker:** `codegraph --version` → `1.3.0-fmagent.N` identifies a build
from this fork.

**Releases:** tagged `vX.Y.Z-fmagent.N` on this repo, each carrying
self-contained per-OS bundles (darwin/linux, arm64/x64). FM-Agent's `install.sh`
pins one via `CODEGRAPH_VERSION`.

**Policy:** pin to a base, don't chase upstream. Upstream is tracked via the
`upstream` git remote (not a local branch). Retire this fork once upstream ships
the #1211 fix in a release.
34 changes: 34 additions & 0 deletions __tests__/extraction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3964,6 +3964,40 @@ class APXCharacter { // the one real definition
});
});

describe('C macro-attribute + typedef return type misparse (#1211)', () => {
const cNames = (code: string) =>
extractFromSource('main.c', code).nodes
.filter((n) => n.kind === 'function')
.map((n) => n.name);

it('recovers the function name when a macro attribute precedes a typedef return type', () => {
const code = `
#define SEC_ATTR __attribute__((section(".init")))
typedef unsigned int UINT32;
#define VOID void

SEC_ATTR VOID GoodName(VOID) { }
SEC_ATTR UINT32 LostName(VOID) { return 0; }
`;
const names = cNames(code);
expect(names).toContain('GoodName');
expect(names).toContain('LostName');
expect(names).not.toContain('(VOID)');
});

it('handles multiple leading macro tokens before a known return type', () => {
const code = `
LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(void) { return 0; }
`;
expect(cNames(code)).toContain('LOS_KernelInit');
});

it('does not blank a real mixed-case return type', () => {
const code = `int normalFunc(void) { return 0; }`;
expect(cNames(code)).toContain('normalFunc');
});
});

describe('C++ templated base-class inheritance (#1043)', () => {
// Inheriting from a template (`class D : public Base<int>`) recorded the base
// ref as the full instantiation `Base<int>`, which never name-matched the
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@colbymchenry/codegraph",
"version": "1.3.0",
"version": "1.3.0-fmagent.1",
"description": "Supercharge AI coding agents with semantic code intelligence — surgical context, fewer tool calls, faster answers. 100% local.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
32 changes: 28 additions & 4 deletions src/extraction/languages/c-cpp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -701,11 +701,35 @@ function preParseCppSource(source: string, filePath?: string): string {
return blanked;
}

/** C source pre-processing: C-detected headers in CUDA projects (llm.c keeps
* `__device__` helpers and kernel prototypes in plain `.h`) get the same
* content-gated CUDA blank as C++. */
/**
* Blank isolated ALL_CAPS macro tokens sitting before a known C return type at
* line start. Handles project-specific attribute/section macros (SEC_ATTR,
* LITE_OS_SEC_TEXT_INIT, etc.) that no curated list can cover. tree-sitter-c
* can't reconcile an unknown token before a typedef'd return type — the
* function name is lost and replaced by the parameter list (#1211).
*
* Matched tightly: ALL_CAPS tokens only, at line start only, and must be
* followed by a known primitive or common typedef return type — so real
* declarations like `HRESULT DoIt()` (mixed-case) are never touched.
*/
const C_LEADING_MACRO_RE =
/^(\s*)((?:[A-Z_][A-Z0-9_]*\s+)+)((?:unsigned\s+|signed\s+|long\s+|short\s+)?(?:void|int|char|short|long|float|double|bool|size_t|ssize_t|ptrdiff_t|u?int(?:8|16|32|64|ptr)_t|VOID|BOOL|BOOLEAN|BYTE|WORD|DWORD|UINT8|UINT16|UINT32|UINT64|INT8|INT16|INT32|INT64|UINTPTR|CHAR|UCHAR|WCHAR|ULONG|LONG|USHORT|SHORT|HANDLE|HRESULT|NTSTATUS|PVOID|LPVOID)\s)/gm;
function blankCLeadingMacros(source: string): string {
return source.replace(
C_LEADING_MACRO_RE,
(_match, indent: string, macros: string, retType: string) =>
indent + ' '.repeat(macros.length) + retType,
);
}

/** C source pre-processing: blank macro tokens that tree-sitter-c can't
* reconcile before return types (#1211), plus known inline-specifier macros
* shared with C++ (SQLITE_API, WINAPI, etc.), and CUDA constructs in
* C-detected headers. */
function preParseCSource(source: string): string {
return looksLikeCudaSource(source) ? blankCudaConstructs(source) : source;
let result = blankCLeadingMacros(blankCppInlineMacros(source));
if (looksLikeCudaSource(source)) result = blankCudaConstructs(result);
return result;
}

export const cppExtractor: LanguageExtractor = {
Expand Down