fix(extraction): detect export-macro-annotated class in .h language check (#1159) (#1207)

Carries #1133 forward onto current main (rebased for conflicts). A lean Unreal-Engine-style `.h` whose only C++ signal is `class ENGINE_API Foo : public Bar` (no public:/virtual/namespace/template) was misdetected as C and its class + inheritance edge silently dropped; looksLikeCpp now recognizes the export-macro-annotated class/struct shape, matching what blankCppExportMacros already recovers.

Fixes #1159.

Co-Authored-By: robertyluo <robertyluo@tencent.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-07-07 12:19:10 -05:00
committed by GitHub
co-authored by robertyluo Claude Opus 4.8
parent 8db8ad5e90
commit c049d9eb0d
3 changed files with 36 additions and 1 deletions
+10 -1
View File
@@ -394,7 +394,16 @@ export function detectLanguage(filePath: string, source?: string, overrides?: Re
*/
function looksLikeCpp(source: string): boolean {
const sample = source.substring(0, 8192);
return /\bnamespace\b|\bclass\s+\w+\s*[:{]|\btemplate\s*<|\b(?:public|private|protected)\s*:|\bvirtual\b|\busing\s+(?:namespace\b|\w+\s*=)/.test(sample);
// The `class MACRO Name : Base` / `class MACRO Name { … }` branch mirrors what
// `blankCppExportMacros` recovers: an ALL-CAPS export/visibility macro
// (`ENGINE_API`, `MYMODULE_API`, `*_EXPORT`, …) sitting between `class`/`struct`
// and the type name. Without it, a header whose ONLY C++ signal is such a
// macro-annotated class — common for lean Unreal-Engine types that carry just
// `GENERATED_BODY()` and no explicit `public:`/`virtual` — is misdetected as C,
// routed through the C extractor (which extracts no classes), and its class
// definition silently vanishes. The two-token shape (`<KW> <MACRO> <Name>`
// before a `[:{]`) never occurs in valid C, so this can't misclassify C headers.
return /\bnamespace\b|\bclass\s+\w+\s*[:{]|\b(?:class|struct)\s+[A-Z][A-Z0-9_]+\s+\w+\s*(?:final\s*)?[:{]|\btemplate\s*<|\b(?:public|private|protected)\s*:|\bvirtual\b|\busing\s+(?:namespace\b|\w+\s*=)/.test(sample);
}
/**