Files
codegraph/__tests__/preload-languages.test.ts
T
e720f6ca53 fix(extraction): preload the Objective-C grammar for C-family headers (#1628) (#1781)
Land upstream PR #1634 by @maxmilian, commit
8d398a92e30c9df27196bc90833efd674384569d.

Path-only detection classifies .h files as c, so preloading previously
covered c and cpp but missed objc selected by content-aware detection.
Preload objc alongside cpp whenever c is present. Full indexing and
changed-file reindexing now share preloadLanguagesForFiles().

Retain all four upstream unit tests and place the existing #1628 changelog
entry under Unreleased / Fixes / Symbols, tests and the viewer.

Verified fail -> pass on Linux with the reporter's repro.h as the only
source file, without a .m or .mm grammar seed. Before: Objective-C parser
initialization failure, 0 nodes, index state failed. After: Indexed 1 files,
2 nodes, 1 edge, index state complete; node CGRepro finds the class and
errors.log is absent.

Validation: npx tsc && npm run copy-assets passed; rebuilt CLI is executable.
npx vitest run __tests__/preload-languages.test.ts: 4 tests passed.

Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
Co-authored-by: Max Hsu <maxmilian@gmail.com>
2026-09-08 11:51:02 -05:00

42 lines
1.7 KiB
TypeScript

/**
* Grammar preload set for a file list (#1628).
*
* Path-only detection calls every `.h` file C, but parse-time detection reads
* the source and can reclassify it as C++ or Objective-C. Workers only ever
* receive the grammars named by this set, so a header that turns out to be
* Objective-C in a project with no `.m` file had no parser to go to and the
* file failed outright with `Failed to get parser for language: objc`.
*/
import { describe, it, expect } from 'vitest';
import { preloadLanguagesForFiles } from '../src/extraction';
describe('grammar preload set (#1628)', () => {
it('covers both ambiguous readings of a .h file, C++ and Objective-C', () => {
const langs = preloadLanguagesForFiles(['repro.h']);
// Path-only detection says C…
expect(langs).toContain('c');
// …and parse-time detection may say either of these instead.
expect(langs).toContain('cpp');
expect(langs).toContain('objc');
});
it('adds nothing for a project with no C-family headers', () => {
const langs = preloadLanguagesForFiles(['a.ts', 'b.py']);
expect(langs).not.toContain('c');
expect(langs).not.toContain('cpp');
expect(langs).not.toContain('objc');
});
it('does not duplicate a language the files already need', () => {
const langs = preloadLanguagesForFiles(['repro.h', 'seed.m', 'other.cpp']);
expect(langs.filter((l) => l === 'objc')).toHaveLength(1);
expect(langs.filter((l) => l === 'cpp')).toHaveLength(1);
});
it('honors extension overrides when detecting the base set', () => {
const langs = preloadLanguagesForFiles(['weird.frob'], { '.frob': 'python' });
expect(langs).toContain('python');
});
});