feat(resolution): add C/C++ include path resolution (#453)
* feat(resolution): add C/C++ include path resolution Add full import resolution pipeline for C and C++ #include directives, connecting extracted import nodes to actual header files in the project. - Add C/C++ extension resolution (.h, .hpp, .hxx, .cpp, .cc, .cxx) - Add system header filtering with ~80 C and ~80 C++ stdlib headers - Add extractCppImports() for #include import mapping extraction - Add compile_commands.json parsing for -I/-isystem include directories - Add heuristic include dir discovery (include/, src/, lib/, api/) - Add resolveCppIncludePath() for include directory search - Add C/C++ built-in symbol filtering (printf, malloc, std::*, etc.) - Wire getCppIncludeDirs into ResolutionContext - Add 13 new tests for C/C++ import resolution and extraction Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * review: wire #include resolution into pipeline + fix builtin filter The PR landed the include-dir scan logic (loadCppIncludeDirs + resolveCppIncludePath) but the indexer never reached it: imports references with referenceName='X.h' fell into resolveViaImport's symbol-lookup branch (matched extractCppImports' basename-without-ext localName via .startsWith, then tried to find a symbol named like the extension and failed). End result on bitcoin-core: 0 new file→file imports vs main, despite the include-dir scan resolving paths correctly when probed directly. resolveViaImport now has a C/C++ imports branch that resolves the include path to the actual file node and returns that — skipping the irrelevant symbol scan. Measured on bitcoin-core: +2,059 newly resolved file→file imports (6,027 → 8,086, +34%). The unconditional CPP_BUILT_INS / C_BUILT_INS filter also misfired: C/C++ codebases routinely shadow stdlib names (bitcoin's mp::move, custom allocators with free/malloc, stream classes with read/write/ close/open, logging libs wrapping printf). Filtering those names killed legitimate edges — 1,179 → 0 for move(), 33 → 0 for free(), 149 → 7 for write() on bitcoin. The filter now defers to hasAnyPossibleMatch: only filter when no user-defined symbol with the name exists. std:: prefix stays unconditional (never user-shadowed in practice). After: printf/free/open/close/read/write/swap all preserved at main's counts; the std::move-binds-to-mp::move false-positives still drop (correctly: −2,154 C/C++ calls). Also: drop the duplicate 'FILE' in C_BUILT_INS; add an end-to-end test that asserts `#include "X.h"` produces a file→file imports edge in the real indexing pipeline (not just direct resolver probes); add a test documenting the cross-language `.h` heuristic claim (Obj-C dirs are intentionally allowed as C/C++ include dirs); add CHANGELOG entry under [Unreleased] with measured numbers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Colby McHenry <me@colbymchenry.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
Colby McHenry
parent
893256b88e
commit
48eebe1e3e
@@ -2070,6 +2070,27 @@ end
|
||||
expect(names).toContain('vector');
|
||||
expect(names).toContain('config.h');
|
||||
});
|
||||
|
||||
it('should create unresolved references for local includes', () => {
|
||||
const code = `#include "myheader.h"`;
|
||||
const result = extractFromSource('main.cpp', code);
|
||||
|
||||
const importRef = result.unresolvedReferences.find(
|
||||
(r) => r.referenceKind === 'imports' && r.referenceName === 'myheader.h'
|
||||
);
|
||||
expect(importRef).toBeDefined();
|
||||
expect(importRef?.line).toBe(1);
|
||||
});
|
||||
|
||||
it('should create unresolved references for system includes', () => {
|
||||
const code = `#include <iostream>`;
|
||||
const result = extractFromSource('main.cpp', code);
|
||||
|
||||
const importRef = result.unresolvedReferences.find(
|
||||
(r) => r.referenceKind === 'imports' && r.referenceName === 'iostream'
|
||||
);
|
||||
expect(importRef).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dart imports', () => {
|
||||
|
||||
Reference in New Issue
Block a user